Cómo cambiar el tamaño de la imagen mediante progtwigción en Object-C en el iPhone

Tengo una aplicación donde estoy mostrando imágenes grandes en un espacio pequeño. Las imágenes son bastante grandes, pero solo las visualizo en marcos de 100×100 píxeles. Mi aplicación está respondiendo lentamente debido al tamaño de las imágenes que estoy usando.

Para mejorar el rendimiento, ¿cómo puedo cambiar el tamaño de las imágenes mediante progtwigción usando Objective-C?

Por favor encuentra el siguiente código

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

Este código es solo para cambiar la escala de la imagen, no para cambiar el tamaño. Debe establecer CGSize como el ancho y alto de su imagen para que la imagen no se estire y se acomode en el medio.

 - (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; } 

Mi forma favorita de hacerlo es con CGImageSourceCreateThumbnailAtIndex (en el marco de ImageIO). El nombre es un poco engañoso.

Aquí hay un fragmento de un código de una aplicación reciente mía.

 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); 

Si usa una imagen en diferentes tamaños y cambia el tamaño cada vez, se degradará el rendimiento de su aplicación. La solución es no cambiar el tamaño de ellos simplemente use el botón en lugar de la vista de imagen. y simplemente configure la imagen en el botón, cambiará el tamaño automáticamente y obtendrá un gran rendimiento.

También estaba cambiando el tamaño de las imágenes mientras las configuraba en la celda, pero mi aplicación se volvió lenta Así que utilicé el botón en lugar de la vista de la imagen (sin cambiar el tamaño de las imágenes progtwigticamente el botón está haciendo este trabajo) y está funcionando perfectamente bien.

  -(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. 

Dado que el código funcionaba perfectamente bien en iOS 4, para la compatibilidad con versiones anteriores agregué un cheque para la versión del sistema operativo y para cualquier cosa por debajo de 5.0 el código anterior funcionaría.

 - (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]; } 

Puedes usar esto

[m_Image.layer setMinificationFilter:kCAFilterTrilinear];

Este hilo es viejo, pero es lo que hice cuando intenté resolver este problema. Una vez que la imagen se escala, no se mostraba bien en mi contenedor a pesar de que desactivaba el diseño automático. La forma más fácil para mí de resolver esto para mostrar en una fila de la mesa, era pintar la imagen sobre un fondo blanco que tenía un tamaño fijo.

Función de ayuda

 +(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; } 

Lo llamé así desde mi vista de tabla 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]; } }];