Подтвердить что ты не робот

Как изменить размер изображения программно в objective-c в iphone

У меня есть приложение, где я показываю большие изображения в небольшом пространстве. Изображения довольно большие, но я показываю их только в кадрах 100x100 пикселей. Мое приложение медленно реагирует из-за размера изображений, которые я использую.

Чтобы повысить производительность, как программно изменить размер изображений с помощью Objective-C?

4b9b3361

Ответ 1

Пожалуйста, найдите следующий код.

- (UIImage *)imageWithImage:(UIImage *)image convertToSize:(CGSize)size {
    UIGraphicsBeginImageContext(size);
    [image drawInRect:CGRectMake(0, 0, size.width, size.height)];
    UIImage *destImage = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();
    return destImage;
}

Ответ 2

Этот код предназначен только для изменения масштаба изображения, а не для изменения размера. Вы должны установить CGSize в качестве ширины и высоты изображения, чтобы изображение не растягивалось и располагалось посередине.

- (UIImage *)imageWithImage:(UIImage *)image scaledToFillSize:(CGSize)size
{
    CGFloat scale = MAX(size.width/image.size.width, size.height/image.size.height);
    CGFloat width = image.size.width * scale;
    CGFloat height = image.size.height * scale;
    CGRect imageRect = CGRectMake((size.width - width)/2.0f,
                                  (size.height - height)/2.0f,
                                  width,
                                  height);

    UIGraphicsBeginImageContextWithOptions(size, NO, 0);
    [image drawInRect:imageRect];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

Ответ 3

Мой любимый способ сделать это - CGImageSourceCreateThumbnailAtIndex (в среде ImageIO). Имя немного вводит в заблуждение.

Вот фрагмент кода из недавнего моего приложения.

CGFloat maxw = // whatever;
CGFloat maxh = // whatever;

CGImageSourceRef src = NULL;
if ([imageSource isKindOfClass:[NSURL class]])
    src = CGImageSourceCreateWithURL((__bridge CFURLRef)imageSource, nil);
else if ([imageSource isKindOfClass:[NSData class]])
    src = CGImageSourceCreateWithData((__bridge CFDataRef)imageSource, nil);

// if at double resolution, double the thumbnail size and use double-resolution image
CGFloat scale = 1;
if ([[UIScreen mainScreen] scale] > 1.0) {
    scale = 2;
    maxw *= 2;
    maxh *= 2;
}

// load the image at the desired size
NSDictionary* d = @{
                    (id)kCGImageSourceShouldAllowFloat: (id)kCFBooleanTrue,
                    (id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue,
                    (id)kCGImageSourceCreateThumbnailFromImageAlways: (id)kCFBooleanTrue,
                    (id)kCGImageSourceThumbnailMaxPixelSize: @((int)(maxw > maxh ? maxw : maxh))
                    };
CGImageRef imref = CGImageSourceCreateThumbnailAtIndex(src, 0, (__bridge CFDictionaryRef)d);
if (NULL != src)
    CFRelease(src);
UIImage* im = [UIImage imageWithCGImage:imref scale:scale orientation:UIImageOrientationUp];
if (NULL != imref)
    CFRelease(imref);

Ответ 4

Если вы используете изображение разных размеров и изменяете размер каждый раз, это ухудшит производительность вашего приложения. Решение не изменяет размер, просто используйте кнопку вместо изображения. и просто установите изображение на кнопке, оно автоматически изменится, и вы получите отличную производительность.

Я также изменял размер изображений, устанавливая его на ячейку, но мое приложение стало медленным. Поэтому я использовал Button вместо изображения (не изменяя размер изображения, программно кнопка выполняет эту работу), и он работает отлично.

Ответ 5

   -(UIImage *)scaleImage:(UIImage *)image toSize:.     (CGSize)targetSize
   {
//If scaleFactor is not touched, no scaling will occur
   CGFloat scaleFactor = 1.0;

//Deciding which factor to use to scale the image (factor = targetSize / imageSize)
if (image.size.width > targetSize.width || 
   image.size.height > targetSize.height || image.size.width == image.size.height)
    if (!((scaleFactor = (targetSize.width / 
    image.size.width)) > (targetSize.height / 
      image.size.height))) //scale to fit width, or
        scaleFactor = targetSize.height / image.size.height; // scale to fit heigth.

Ответ 6

Так как код отлично работал в iOS 4, для обратной совместимости я добавил проверку на версию ОС и для чего-либо ниже 5.0 работал бы старый код.

- (UIImage *)resizedImage:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)quality {
    BOOL drawTransposed;
    CGAffineTransform transform = CGAffineTransformIdentity;

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0) {
        // Apprently in iOS 5 the image is already correctly rotated, so we don't need to rotate it manually
        drawTransposed = NO;  
    } else {    
        switch (self.imageOrientation) {
            case UIImageOrientationLeft:
            case UIImageOrientationLeftMirrored:
            case UIImageOrientationRight:
            case UIImageOrientationRightMirrored:
                drawTransposed = YES;
                break;

            default:
                drawTransposed = NO;
        }

        transform = [self transformForOrientation:newSize];
    } 

    return [self resizedImage:newSize
                    transform:transform
               drawTransposed:drawTransposed
         interpolationQuality:quality];
}

Ответ 7

Вы можете использовать это.

[m_Image.layer setMinificationFilter:kCAFilterTrilinear];

Ответ 8

Эта ветка устарела, но я пытаюсь решить эту проблему. Как только изображение масштабируется, оно не отображается хорошо в моем контейнере, даже если я отключил автомат. Самый простой способ разрешить это для отображения в строке таблицы - это рисовать изображение на белом фоне с фиксированным размером.

Вспомогательная функция

+(UIImage*)scaleMaintainAspectRatio:(UIImage*)sourceImage :(float)i_width :(float)i_height
{
float newHeight = 0.0;
float newWidth = 0.0;

float oldWidth = sourceImage.size.width;
float widthScaleFactor = i_width / oldWidth;

float oldHeight = sourceImage.size.height;
float heightScaleFactor = i_height / oldHeight;
if (heightScaleFactor > widthScaleFactor) {
    newHeight = oldHeight * widthScaleFactor;
    newWidth = sourceImage.size.width * widthScaleFactor;
} else {
    newHeight = sourceImage.size.height * heightScaleFactor;
    newWidth = oldWidth * heightScaleFactor;
}

// return image in white rect
float cxPad = i_width - newWidth;
float cyPad = i_height - newHeight;
if (cyPad > 0) {
    cyPad = cyPad / 2.0;
}
if (cxPad > 0) {
    cxPad = cxPad / 2.0;
}

CGSize size = CGSizeMake(i_width, i_height);
UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width, size.height), YES, 0.0);
[[UIColor whiteColor] setFill];
UIRectFill(CGRectMake(0, 0, size.width, size.height));
[sourceImage drawInRect:CGRectMake((int)cxPad, (int)cyPad, newWidth, newHeight)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;

// will return scaled image at actual size, not in white rect
// UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
// [sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
// UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
// UIGraphicsEndImageContext();
// return newImage;
}

Я назвал это так из моего представления таблицы cellForRowAtIndexPath

    PFFile *childsPicture = [object objectForKey:@"picture"];
[childsPicture getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
    if (!error) {
        UIImage *largePicture = [UIImage imageWithData:imageData];
        UIImage *scaledPicture = [Utility scaleMaintainAspectRatio:largePicture :70.0 :70.0 ];
        PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
        thumbnailImageView.image = scaledPicture;
        [self.tableView reloadData];
    }
}];

Ответ 9

Привет с конца 2018. Решено следующим решением (вам нужна только последняя строка, первая и вторая только для объяснения):

NSURL *url = [NSURL URLWithString:response.json[0][@"photo_50"]];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data scale:customScale];

"customScale" - это масштаб, который вы хотите (> 1, если изображение должно быть меньше, <1, если изображение должно быть больше).