如何在Swift中调整图像大小?

我正在使用Swift和Parse.com为iOS创build一个应用程序

我试图让用户从图像select器中select一张图片,然后在上传到我的后端之前将所选图像的大小调整为200×200像素。

Parse.com有一个名为“AnyPic”的Instagram复制应用程序的教程,它给出了调整图像大小的代码,但它在Objective-C中。

// Resize the image to be square (what is shown in the preview) UIImage *resizedImage = [anImage resizedImageWithContentMode:UIViewContentModeScaleAspectFit bounds:CGSizeMake(560.0f, 560.0f) interpolationQuality:kCGInterpolationHigh]; // Create a thumbnail and add a corner radius for use in table views UIImage *thumbnailImage = [anImage thumbnailImage:86.0f transparentBorder:0.0f cornerRadius:10.0f interpolationQuality:kCGInterpolationDefault]; 

如何在Swift中创build200x200px的选定图片(然后上传)?

而且,thumbnailImage函数在做什么?

图像调整function如下图所示。

 func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage { let size = image.size let widthRatio = targetSize.width / size.width let heightRatio = targetSize.height / size.height // Figure out what our orientation is, and use that to form the rectangle var newSize: CGSize if(widthRatio > heightRatio) { newSize = CGSizeMake(size.width * heightRatio, size.height * heightRatio) } else { newSize = CGSizeMake(size.width * widthRatio, size.height * widthRatio) } // This is the rect that we've calculated out and this is what is actually used below let rect = CGRectMake(0, 0, newSize.width, newSize.height) // Actually do the resizing to the rect using the ImageContext stuff UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) image.drawInRect(rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage } 

使用上述function,并使用200 * 200作为下面的代码调整图像大小

 self.resizeImage(UIImage(named: "yourImageName")!, targetSize: CGSizeMake(200.0, 200.0)) 

请参阅我的博客post, 以快速和客观的C调整图像大小 ,以获取更多详细信息。

swift3更新

  func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage { let size = image.size let widthRatio = targetSize.width / size.width let heightRatio = targetSize.height / size.height // Figure out what our orientation is, and use that to form the rectangle var newSize: CGSize if(widthRatio > heightRatio) { newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio) } else { newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio) } // This is the rect that we've calculated out and this is what is actually used below let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height) // Actually do the resizing to the rect using the ImageContext stuff UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) image.draw(in: rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } 

由于@KiritModi的答案是从2015年起,这是Swift 3.0的版本:

 func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage { let size = image.size let widthRatio = targetSize.width / image.size.width let heightRatio = targetSize.height / image.size.height // Figure out what our orientation is, and use that to form the rectangle var newSize: CGSize if(widthRatio > heightRatio) { newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio) } else { newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio) } // This is the rect that we've calculated out and this is what is actually used below let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height) // Actually do the resizing to the rect using the ImageContext stuff UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) image.draw(in: rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } 

也可以使用AlamofireImage( https://github.com/Alamofire/AlamofireImage

 let size = CGSize(width: 30.0, height: 30.0) let aspectScaledToFitImage = image.af_imageAspectScaled(toFit: size) 

前一篇文章中的函数给了我一个模糊的结果。

对于Swift 4.0和iOS 10

  extension UIImage { func resizeImage(_ dimension: CGFloat, opaque: Bool, contentMode: UIViewContentMode = .scaleAspectFit) -> UIImage { var width: CGFloat var height: CGFloat var newImage: UIImage let size = self.size let aspectRatio = size.width/size.height switch contentMode { case .scaleAspectFit: if aspectRatio > 1 { // Landscape image width = dimension height = dimension / aspectRatio } else { // Portrait image height = dimension width = dimension * aspectRatio } default: fatalError("UIIMage.resizeToFit(): FATAL: Unimplemented ContentMode") } if #available(iOS 10.0, *) { let renderFormat = UIGraphicsImageRendererFormat.default() renderFormat.opaque = opaque let renderer = UIGraphicsImageRenderer(size: CGSize(width: width, height: height), format: renderFormat) newImage = renderer.image { (context) in self.draw(in: CGRect(x: 0, y: 0, width: width, height: height)) } } else { UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), opaque, 0) self.draw(in: CGRect(x: 0, y: 0, width: width, height: height)) newImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() } return newImage } } 

Swift 3版本和扩展风格

这个答案来自@Kirit Modi。

 extension UIImage { func resizeImage(targetSize: CGSize) -> UIImage { let size = self.size let widthRatio = targetSize.width / size.width let heightRatio = targetSize.height / size.height // Figure out what our orientation is, and use that to form the rectangle var newSize: CGSize if(widthRatio > heightRatio) { newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio) } else { newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio) } // This is the rect that we've calculated out and this is what is actually used below let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height) // Actually do the resizing to the rect using the ImageContext stuff UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) self.draw(in: rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } } 

这里有两个简单的UIImage扩展函数:

 func scaledWithMaxWidthOrHeightValue(value: CGFloat) -> UIImage? { let width = self.size.width let height = self.size.height let ratio = width/height var newWidth = value var newHeight = value if ratio > 1 { newWidth = width * (newHeight/height) } else { newHeight = height * (newWidth/width) } UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: newHeight), false, 0) draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight)) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image! } func scaled(withScale scale: CGFloat) -> UIImage? { let size = CGSize(width: self.size.width * scale, height: self.size.height * scale) UIGraphicsBeginImageContextWithOptions(size, false, 0) draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image } 

示例是将图像最小化为1024或更less

func resizeImage(image:UIImage) – > UIImage {

  if image.size.height >= 1024 && image.size.width >= 1024 { UIGraphicsBeginImageContext(CGSize(width:1024, height:1024)) image.draw(in: CGRect(x:0, y:0, width:1024, height:1024)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } else if image.size.height >= 1024 && image.size.width < 1024 { UIGraphicsBeginImageContext(CGSize(width:image.size.width, height:1024)) image.draw(in: CGRect(x:0, y:0, width:image.size.width, height:1024)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } else if image.size.width >= 1024 && image.size.height < 1024 { UIGraphicsBeginImageContext(CGSize(width:1024, height:image.size.height)) image.draw(in: CGRect(x:0, y:0, width:1024, height:image.size.height)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } else { return image } } 

你可以在Swift 3中使用这个合适的图像;

 extension UIImage { func resizedImage(newSize: CGSize) -> UIImage { // Guard newSize is different guard self.size != newSize else { return self } UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0); self.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)) let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() return newImage } func resizedImageWithinRect(rectSize: CGSize) -> UIImage { let widthFactor = size.width / rectSize.width let heightFactor = size.height / rectSize.height var resizeFactor = widthFactor if size.height > size.width { resizeFactor = heightFactor } let newSize = CGSize(width: size.width/resizeFactor, height: size.height/resizeFactor) let resized = resizedImage(newSize: newSize) return resized } } 

用法;

 let resizedImage = image.resizedImageWithinRect(rectSize: CGSize(width: 1900, height: 1900)) 

对于Swift 4,我只需在UIImage上引用自己的扩展即可。

 import UIKit extension UIImage { func resizeImage(targetSize: CGSize) -> UIImage { let size = self.size let widthRatio = targetSize.width / size.width let heightRatio = targetSize.height / size.height let newSize = widthRatio > heightRatio ? CGSize(width: size.width * heightRatio, height: size.height * heightRatio) : CGSize(width: size.width * widthRatio, height: size.height * widthRatio) let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height) UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) self.draw(in: rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } }