Cambia el tamaño de UIImage manteniendo la relación de aspecto y ancho

Lo he visto en muchas publicaciones para cambiar el tamaño de la imagen manteniendo la relación de aspecto. Estas funciones usan los puntos fijos (ancho y alto) para RECT mientras se cambia el tamaño. Pero en mi proyecto, necesito cambiar el tamaño de la vista en función del ancho solo, la altura debe tomarse automáticamente en función de la relación de aspecto. Alguien me ayude a lograr esto.

El método de Srikar funciona muy bien, si conoce tanto el alto como el ancho de su nuevo Tamaño. Si, por ejemplo, solo conoce el ancho al que desea escalar y no le importa la altura, primero debe calcular el factor de escala de la altura.

+(UIImage*)imageWithImage: (UIImage*) sourceImage scaledToWidth: (float) i_width { float oldWidth = sourceImage.size.width; float scaleFactor = i_width / oldWidth; float newHeight = sourceImage.size.height * scaleFactor; float newWidth = oldWidth * scaleFactor; UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight)); [sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

Si no sabe si la imagen será vertical u horizontal (por ejemplo, el usuario toma una foto con la cámara), creé otro método que toma los parámetros de ancho y alto máximo.

Digamos que tienes un UIImage *myLargeImage que tiene una relación de 4: 3.

 UIImage *myResizedImage = [ImageUtilities imageWithImage:myLargeImage scaledToMaxWidth:1024 maxHeight:1024]; 

El UIImage redimensionado será 1024×768 si el paisaje; 768×1024 si retrato. Este método también generará imágenes de alta resolución para la visualización de la retina.

 + (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)size { if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { UIGraphicsBeginImageContextWithOptions(size, NO, [[UIScreen mainScreen] scale]); } else { UIGraphicsBeginImageContext(size); } [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } + (UIImage *)imageWithImage:(UIImage *)image scaledToMaxWidth:(CGFloat)width maxHeight:(CGFloat)height { CGFloat oldWidth = image.size.width; CGFloat oldHeight = image.size.height; CGFloat scaleFactor = (oldWidth > oldHeight) ? width / oldWidth : height / oldHeight; CGFloat newHeight = oldHeight * scaleFactor; CGFloat newWidth = oldWidth * scaleFactor; CGSize newSize = CGSizeMake(newWidth, newHeight); return [ImageUtilities imageWithImage:image scaledToSize:newSize]; } 

Gracias @ Maverick1st el algoritmo, lo implementé a Swift , en mi caso la altura es el parámetro de entrada

 class func resizeImage(image: UIImage, newHeight: CGFloat) -> UIImage { let scale = newHeight / image.size.height let newWidth = image.size.width * scale UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight)) image.drawInRect(CGRectMake(0, 0, newWidth, newHeight)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage } 

La mejor respuesta Maverick 1st’s correctamente traducido a Swift (trabajando con el último swift 3 ):

 func imageWithImage (sourceImage:UIImage, scaledToWidth: CGFloat) -> UIImage { let oldWidth = sourceImage.size.width let scaleFactor = scaledToWidth / oldWidth let newHeight = sourceImage.size.height * scaleFactor let newWidth = oldWidth * scaleFactor UIGraphicsBeginImageContext(CGSize(width:newWidth, height:newHeight)) sourceImage.draw(in: CGRect(x:0, y:0, width:newWidth, height:newHeight)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } 

Este método es una categoría en UIImage. Hace escala para caber en pocas líneas de código usando AVFoundation. No olvides importar #import .

 @implementation UIImage (Helper) - (UIImage *)imageScaledToFitToSize:(CGSize)size { CGRect scaledRect = AVMakeRectWithAspectRatioInsideRect(self.size, CGRectMake(0, 0, size.width, size.height)); UIGraphicsBeginImageContextWithOptions(size, NO, 0); [self drawInRect:scaledRect]; UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return scaledImage; } @end 

La forma más simple es establecer el marco de su UIImageView y establecer el modo de contentMode a una de las opciones de cambio de tamaño.

El código es el siguiente: se puede usar como un método de utilidad.

 + (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize { UIGraphicsBeginImageContext(newSize); [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

Bueno, aquí tenemos pocas buenas respuestas para cambiar el tamaño de la imagen, pero solo las modifico según mi necesidad. Espero que esto ayude a alguien como yo.

Mi requisito era

  1. Si el ancho de la imagen es mayor a 1920, redimensione con un ancho de 1920 y mantenga la altura con la relación de aspecto original.
  2. Si la altura de la imagen es superior a 1080, modifíquela con una altura de 1080 y mantenga el ancho con la relación de aspecto original.

  if (originalImage.size.width > 1920) { CGSize newSize; newSize.width = 1920; newSize.height = (1920 * originalImage.size.height) / originalImage.size.width; originalImage = [ProfileEditExperienceViewController imageWithImage:originalImage scaledToSize:newSize]; } if (originalImage.size.height > 1080) { CGSize newSize; newSize.width = (1080 * originalImage.size.width) / originalImage.size.height; newSize.height = 1080; originalImage = [ProfileEditExperienceViewController imageWithImage:originalImage scaledToSize:newSize]; } + (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize { UIGraphicsBeginImageContext(newSize); [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

Gracias a @ Srikar Appal , por cambiar el tamaño, he usado su método.

Es posible que desee comprobar esto también para el cálculo del tamaño.

Progtwigdo:

 imageView.contentMode = UIViewContentModeScaleAspectFit; 

Storyboard:

enter image description here

Solo importe AVFoundation y use AVMakeRectWithAspectRatioInsideRect(CGRectCurrentSize, CGRectMake(0, 0, YOUR_WIDTH, CGFLOAT_MAX)

Para mejorar la respuesta de Ryan:

  + (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)size { CGFloat oldWidth = image.size.width; CGFloat oldHeight = image.size.height; //You may need to take some retina adjustments into consideration here CGFloat scaleFactor = (oldWidth > oldHeight) ? width / oldWidth : height / oldHeight; return [UIImage imageWithCGImage:image.CGImage scale:scaleFactor orientation:UIImageOrientationUp]; } 

Ryan’s Solution @Ryan en código rápido

utilizar:

  func imageWithSize(image: UIImage,size: CGSize)->UIImage{ if UIScreen.mainScreen().respondsToSelector("scale"){ UIGraphicsBeginImageContextWithOptions(size,false,UIScreen.mainScreen().scale); } else { UIGraphicsBeginImageContext(size); } image.drawInRect(CGRectMake(0, 0, size.width, size.height)); var newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } //Summon this function VVV func resizeImageWithAspect(image: UIImage,scaledToMaxWidth width:CGFloat,maxHeight height :CGFloat)->UIImage { let oldWidth = image.size.width; let oldHeight = image.size.height; let scaleFactor = (oldWidth > oldHeight) ? width / oldWidth : height / oldHeight; let newHeight = oldHeight * scaleFactor; let newWidth = oldWidth * scaleFactor; let newSize = CGSizeMake(newWidth, newHeight); return imageWithSize(image, size: newSize); } 

Lo he resuelto de una manera mucho más simple

 UIImage *placeholder = [UIImage imageNamed:@"OriginalImage.png"]; self.yourImageview.image = [UIImage imageWithCGImage:[placeholder CGImage] scale:(placeholder.scale * 1.5) orientation:(placeholder.imageOrientation)]; 

El multiplicador de la escala definirá el escalado de la imagen, más el multiplicador reducirá la imagen. para que pueda verificar qué se ajusta a su pantalla.

O también puede obtener el multiplicador dividiendo el ancho de la imagen / ancho de la pantalla.

En Swift 3 hay algunos cambios. Aquí hay una extensión de UIImage:

 public extension UIImage { public func resize(height: CGFloat) -> UIImage? { let scale = height / self.size.height let width = self.size.width * scale UIGraphicsBeginImageContext(CGSize(width: width, height: height)) self.draw(in: CGRect(x:0, y:0, width:width, height:height)) let resultImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return resultImage } } 

Este fue perfecto para mí. Mantiene la relación de aspecto y toma un maxLength . El ancho o la altura no serán más que maxLength

 -(UIImage*)imageWithImage: (UIImage*) sourceImage maxLength: (float) maxLength { CGFloat scaleFactor = maxLength / MAX(sourceImage.size.width, sourceImage.size.height); float newHeight = sourceImage.size.height * scaleFactor; float newWidth = sourceImage.size.width * scaleFactor; UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight)); [sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

Calcula la mejor altura de la imagen para el ancho disponible.

 import Foundation public extension UIImage { public func height(forWidth width: CGFloat) -> CGFloat { let boundingRect = CGRect( x: 0, y: 0, width: width, height: CGFloat(MAXFLOAT) ) let rect = AVMakeRect( aspectRatio: size, insideRect: boundingRect ) return rect.size.height } } 
    Intereting Posts