调整UIImage的最简单的方法是什么?

在我的iPhone应用程序中,我用相机拍了一张照片,然后我想把它调整到290 * 390像素。 我正在使用这种方法来调整图像大小:

UIImage *newImage = [image _imageScaledToSize:CGSizeMake(290, 390) interpolationQuality:1]; 

它完美的工作,但它是一个无证的function,所以我不能用它与iPhone OS4。

所以…调整UIImage的最简单方法是什么?

最简单的方法是设置您的UIImageView的框架,并将contentMode设置为resize选项之一。

或者你可以使用这个实用的方法,如果你真的需要调整图像大小:

 + (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize { //UIGraphicsBeginImageContext(newSize); // In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution). // Pass 1.0 to force exact pixel size. UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0); [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

用法示例:

 #import "MYUtil.h" … UIImage *myIcon = [MYUtil imageWithImage:myUIImageInstance scaledToSize:CGSizeMake(20, 20)]; 

这是Paul Lynch答案的Swift版本

 func imageWithImage(image:UIImage, scaledToSize newSize:CGSize) -> UIImage{ UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0); image.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height)) let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage } 

Swift 3.0版本:

 func imageWithImage(image:UIImage, scaledToSize newSize:CGSize) -> UIImage{ UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0); image.draw(in: CGRect(origin: CGPoint.zero, size: CGSize(width: newSize.width, height: newSize.height))) let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() return newImage } 

Trevor Howard有一些UIImage类别 ,可以很好地处理resize。 如果没有别的,你可以使用代码作为例子。

注意:从iOS 5.1开始,此答案可能无效。 见下面的评论。

我也看到这样做(我使用UIButtons为正常和选定状态,因为button不resize,以适应)。 信用可以追溯到原作者。

首先制作一个名为UIImageResizing.h和UIImageResizing.m的空白.h和.m文件

 // Put this in UIImageResizing.h @interface UIImage (Resize) - (UIImage*)scaleToSize:(CGSize)size; @end // Put this in UIImageResizing.m @implementation UIImage (Resize) - (UIImage*)scaleToSize:(CGSize)size { UIGraphicsBeginImageContext(size); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextTranslateCTM(context, 0.0, size.height); CGContextScaleCTM(context, 1.0, -1.0); CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, size.width, size.height), self.CGImage); UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return scaledImage; } @end 

将.h文件包含在你要使用函数的任何.m文件中,然后像这样调用它:

 UIImage* image = [UIImage imageNamed:@"largeImage.png"]; UIImage* smallImage = [image scaleToSize:CGSizeMake(100.0f,100.0f)]; 

保罗的代码的这种改进将给你一个具有视网膜显示的iPhone上的高清晰度的图像。 否则,缩小它是模糊的。

 + (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize { if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { if ([[UIScreen mainScreen] scale] == 2.0) { UIGraphicsBeginImageContextWithOptions(newSize, YES, 2.0); } else { UIGraphicsBeginImageContext(newSize); } } else { UIGraphicsBeginImageContext(newSize); } [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

这是对上面的iWasRobbed所写类别的修改。 它保持原始图像的纵横比而不是扭曲它。

 - (UIImage*)scaleToSizeKeepAspect:(CGSize)size { UIGraphicsBeginImageContext(size); CGFloat ws = size.width/self.size.width; CGFloat hs = size.height/self.size.height; if (ws > hs) { ws = hs/ws; hs = 1.0; } else { hs = ws/hs; ws = 1.0; } CGContextRef context = UIGraphicsGetCurrentContext(); CGContextTranslateCTM(context, 0.0, size.height); CGContextScaleCTM(context, 1.0, -1.0); CGContextDrawImage(context, CGRectMake(size.width/2-(size.width*ws)/2, size.height/2-(size.height*hs)/2, size.width*ws, size.height*hs), self.CGImage); UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return scaledImage; } 

这是一个简单的方法:

  UIImage * image = [UIImage imageNamed:@"image"]; CGSize sacleSize = CGSizeMake(10, 10); UIGraphicsBeginImageContextWithOptions(sacleSize, NO, 0.0); [image drawInRect:CGRectMake(0, 0, sacleSize.width, sacleSize.height)]; UIImage * resizedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 

resizedImage是一个新的图像。

如果你只是想要一个较小的图像,并不关心确切的大小:

 + (UIImage *)imageWithImage:(UIImage *)image scaledToScale:(CGFloat)scale { UIGraphicsBeginImageContextWithOptions(self.size, YES, scale); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetInterpolationQuality(context, kCGInterpolationHigh); [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

将刻度设置为0.25f将会为您提供来自800万像素摄像头的816乘以612的图像。

这是一个类别UIImage + Scale为那些谁需要。

我在苹果自己的例子中find了UIImage的一个类别,它也有相同的技巧。 链接如下: https : //developer.apple.com/library/ios/samplecode/sc2273/Listings/AirDropSample_UIImage_Resize_m.html 。

你只需要改变电话:

 UIGraphicsBeginImageContextWithOptions(newSize, YES, 2.0); 

imageWithImage:scaledToSize:inRect: with:

 UIGraphicsBeginImageContextWithOptions(newSize, NO, 2.0); 

为了考虑图像中的alpha通道。

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

为什么这么复杂? 我认为使用系统API可以达到相同的结果:

 UIImage *largeImage; CGFloat ratio = 0.4; // you want to get a new image that is 40% the size of large image. UIImage *newImage = [UIImage imageWithCGImage:largeImage.CGImage scale:1/ratio orientation:largeImage.imageOrientation]; // notice the second argument, it is 1/ratio, not ratio. 

唯一的问题是你应该把目标比率的倒数作为第二个参数,因为根据文档第二个参数指定了原始图像与新缩放比例的比值。

如果你想制作一个UIImage的缩略图(比例resize或可能涉及一些裁剪),请查看UIImage + Resize类别,以便使用简洁的ImageMagick语法:

 UIImage* squareImage = [image resizedImageByMagick: @"320x320#"]; 

正确的Swift 3.0 for iOS 10+解决scheme:使用ImageRenderer和闭包语法

  func imageWith(newSize: CGSize) -> UIImage { let renderer = UIGraphicsImageRenderer(size:newSize) let image = renderer.image{_ in self.draw(in: CGRect.init(origin: CGPoint.zero, size: newSize)) } return image } 

罗杰里奥·查韦斯的答案是一个迅速的延伸

 func scaledTo(size: CGSize) -> UIImage{ UIGraphicsBeginImageContextWithOptions(size, false, 0.0); self.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() return newImage } 

还有奖金

 func scaledTo(height: CGFloat) -> UIImage{ let width = height*self.size.width/self.size.height return scaledTo(size: CGSize(width: width, height: height)) } 

斯威夫特3.0与故障安全选项(返回错误的情况下的原始图像):

 func resize(image: UIImage, toSize size: CGSize) -> UIImage{ UIGraphicsBeginImageContextWithOptions(size,false,1.0) image.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) if let resizedImage = UIGraphicsGetImageFromCurrentImageContext() { UIGraphicsEndImageContext() return resizedImage } UIGraphicsEndImageContext() return image } 

保罗·林奇的答案很好,但它会改变图像比例。 如果您不想更改图像比例,并且仍然希望新图像适合新尺寸,请尝试此操作。

 + (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize { // calculate a new size which ratio is same to original image CGFloat ratioW = image.size.width / newSize.width; CGFloat ratioH = image.size.height / newSize.height; CGFloat ratio = image.size.width / image.size.height; CGSize showSize = CGSizeZero; if (ratioW > 1 && ratioH > 1) { if (ratioW > ratioH) { showSize.width = newSize.width; showSize.height = showSize.width / ratio; } else { showSize.height = newSize.height; showSize.width = showSize.height * ratio; } } else if (ratioW > 1) { showSize.width = showSize.width; showSize.height = showSize.width / ratio; } else if (ratioH > 1) { showSize.height = showSize.height; showSize.width = showSize.height * ratio; } //UIGraphicsBeginImageContext(newSize); // In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution). // Pass 1.0 to force exact pixel size. UIGraphicsBeginImageContextWithOptions(showSize, NO, 0.0); [image drawInRect:CGRectMake(0, 0, showSize.width, showSize.height)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage;} 

使用这个扩展名

 extension UIImage { public func resize(size:CGSize, completionHandler:(resizedImage:UIImage, data:NSData?)->()) { dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in let newSize:CGSize = size let rect = CGRectMake(0, 0, newSize.width, newSize.height) UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) self.drawInRect(rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() let imageData = UIImageJPEGRepresentation(newImage, 0.5) dispatch_async(dispatch_get_main_queue(), { () -> Void in completionHandler(resizedImage: newImage, data:imageData) }) }) } } 

[比克里斯]要调整所需的大小:

 UIImage *after = [UIImage imageWithCGImage:before.CGImage scale:CGImageGetHeight(before.CGImage)/DESIREDHEIGHT orientation:UIImageOrientationUp]; 

或者等价replaceCGImageGetWidth(...)/DESIREDWIDTH

在这里,我有点冗长的Swift代码

 func scaleImage(image:UIImage, toSize:CGSize) -> UIImage { UIGraphicsBeginImageContextWithOptions(toSize, false, 0.0); let aspectRatioAwareSize = self.aspectRatioAwareSize(image.size, boxSize: toSize, useLetterBox: false) let leftMargin = (toSize.width - aspectRatioAwareSize.width) * 0.5 let topMargin = (toSize.height - aspectRatioAwareSize.height) * 0.5 image.drawInRect(CGRectMake(leftMargin, topMargin, aspectRatioAwareSize.width , aspectRatioAwareSize.height)) let retVal = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return retVal } func aspectRatioAwareSize(imageSize: CGSize, boxSize: CGSize, useLetterBox: Bool) -> CGSize { // aspect ratio aware size // http://stackoverflow.com/a/6565988/8047 let imageWidth = imageSize.width let imageHeight = imageSize.height let containerWidth = boxSize.width let containerHeight = boxSize.height let imageAspectRatio = imageWidth/imageHeight let containerAspectRatio = containerWidth/containerHeight let retVal : CGSize // use the else at your own risk: it seems to work, but I don't know // the math if (useLetterBox) { retVal = containerAspectRatio > imageAspectRatio ? CGSizeMake(imageWidth * containerHeight / imageHeight, containerHeight) : CGSizeMake(containerWidth, imageHeight * containerWidth / imageWidth) } else { retVal = containerAspectRatio < imageAspectRatio ? CGSizeMake(imageWidth * containerHeight / imageHeight, containerHeight) : CGSizeMake(containerWidth, imageHeight * containerWidth / imageWidth) } return retVal } 

Swift 4和iOS 10+更紧凑的版本:

 extension UIImage { func resized(to size: CGSize) -> UIImage { return UIGraphicsImageRenderer(size: size).image { _ in draw(in: CGRect(origin: .zero, size: size)) } } } 

用法:

 let resizedImage = image.resized(to: CGSize(width: 50, height: 50)) 

这是一个与Swift 3Swift 4兼容的UIImage扩展,它将图像缩放为具有纵横比的给定尺寸

 extension UIImage { func scaledImage(withSize size: CGSize) -> UIImage { UIGraphicsBeginImageContextWithOptions(size, false, 0.0) defer { UIGraphicsEndImageContext() } draw(in: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)) return UIGraphicsGetImageFromCurrentImageContext()! } func scaleImageToFitSize(size: CGSize) -> UIImage { let aspect = self.size.width / self.size.height if size.width / aspect <= size.height { return scaledImage(withSize: CGSize(width: size.width, height: size.width / aspect)) } else { return scaledImage(withSize: CGSize(width: size.height * aspect, height: size.height)) } } } 

用法示例

 let image = UIImage(named: "apple") let scaledImage = image.scaleImageToFitSize(size: CGSize(width: 45.0, height: 45.0)) 

Swift 2.0:

 let image = UIImage(named: "imageName") let newSize = CGSize(width: 10, height: 10) UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0) image?.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height)) let imageResized = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() 

我发现很难find一个可以在Swift 3项目中使用开箱即用的答案。 其他答案的主要问题是他们不尊重图像的alpha通道。 这是我在我的项目中使用的技术。

 extension UIImage { func scaledToFit(toSize newSize: CGSize) -> UIImage { if (size.width < newSize.width && size.height < newSize.height) { return copy() as! UIImage } let widthScale = newSize.width / size.width let heightScale = newSize.height / size.height let scaleFactor = widthScale < heightScale ? widthScale : heightScale let scaledSize = CGSize(width: size.width * scaleFactor, height: size.height * scaleFactor) return self.scaled(toSize: scaledSize, in: CGRect(x: 0.0, y: 0.0, width: scaledSize.width, height: scaledSize.height)) } func scaled(toSize newSize: CGSize, in rect: CGRect) -> UIImage { if UIScreen.main.scale == 2.0 { UIGraphicsBeginImageContextWithOptions(newSize, !hasAlphaChannel, 2.0) } else { UIGraphicsBeginImageContext(newSize) } draw(in: rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage ?? UIImage() } var hasAlphaChannel: Bool { guard let alpha = cgImage?.alphaInfo else { return false } return alpha == CGImageAlphaInfo.first || alpha == CGImageAlphaInfo.last || alpha == CGImageAlphaInfo.premultipliedFirst || alpha == CGImageAlphaInfo.premultipliedLast } } 

使用示例:

 override func viewDidLoad() { super.viewDidLoad() let size = CGSize(width: 14.0, height: 14.0) if let image = UIImage(named: "barbell")?.scaledToFit(toSize: size) { let imageView = UIImageView(image: image) imageView.center = CGPoint(x: 100, y: 100) view.addSubview(imageView) } } 

这段代码是苹果扩展的重写,增加了对带有或不带有alpha通道的图像的支持。

作为进一步阅读,我build议检查这篇文章不同的图像resize技术。 目前的方法提供了不错的性能,它运行高级API并且易于理解。 我build议坚持下去,除非你发现图像resize是你的performance瓶颈。

斯威夫特4回答:

 func scaleDown(image: UIImage, withSize: CGSize) -> UIImage { let scale = UIScreen.main.scale UIGraphicsBeginImageContextWithOptions(withSize, false, scale) image.draw(in: CGRect(x: 0, y: 0, width: withSize.width, height: withSize.height)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } 

(Swift 4兼容)iOS 10+和iOS <10解决scheme(如果可能,使用UIGraphicsImageRenderer ,否则为UIGraphicsGetImageFromCurrentImageContext

 /// Resizes an image /// /// - Parameter newSize: New size /// - Returns: Resized image func scaled(to newSize: CGSize) -> UIImage { let rect = CGRect(origin: .zero, size: newSize) if #available(iOS 10, *) { let renderer = UIGraphicsImageRenderer(size: newSize) return renderer.image { _ in self.draw(in: rect) } } else { UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0) self.draw(in: rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } }