我正在使用此函数调整各种图像的大小:
func resizeImage(image: UIImage) -> UIImage {
var actualHeight: CGFloat = image.size.height
var actualWidth: CGFloat = image.size.width
let maxHeight: CGFloat = 600.0
let maxWidth: CGFloat = text.frame.size.width - 10
var imgRatio: CGFloat = actualWidth / actualHeight
let maxRatio: CGFloat = maxWidth / maxHeight
let compressionQuality: CGFloat = 0.5
//50 percent compression
if actualHeight > maxHeight || actualWidth > maxWidth {
if imgRatio < maxRatio {
//adjust width according to maxHeight
imgRatio = maxHeight / actualHeight
actualWidth = imgRatio * actualWidth
actualHeight = maxHeight
}
else if imgRatio > maxRatio {
//adjust height according to maxWidth
imgRatio = maxWidth / actualWidth
actualHeight = imgRatio * actualHeight
actualWidth = maxWidth
}
else {
actualHeight = maxHeight
actualWidth = maxWidth
}
}
let rect: CGRect = CGRectMake(0.0, 0.0, actualWidth, actualHeight)
UIGraphicsBeginImageContext(rect.size)
image.drawInRect(rect)
let img: UIImage = UIGraphicsGetImageFromCurrentImageContext()
let imageData: NSData = UIImageJPEGRepresentation(img, compressionQuality)!
UIGraphicsEndImageContext()
return UIImage(data: imageData)!
}
但是质量太可怕了....下面是我得到的照片:
我认为图像的质量因压缩质量而异...?从上面的代码中可以看出,我现在已经达到了0.5,但即使我将其改为1,质量仍然很糟糕?
任何想法,
非常感谢。
答案 0 :(得分:2)
您应该使用UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
代替。它将使用您设备的正确比例。您正在使用的版本(没有选项)使用默认比例因子1.0
。使用...WithOptions()
变体并传入0.0
作为比例,默认为设备的本机比例。请注意,这可能不是您想要的。
其次,您可以使用AVMakeRectWithAspectRatioInsideRect()
来计算目标尺寸。第三,您不需要进行JPEG编码,您可以直接返回生成的图像。
结合起来,这大大简化了您的代码:
func resizeImage(image: UIImage) -> UIImage {
let maxSize = CGSize(
width: text.frame.size.width - 10,
height: 600.0
)
let newSize = AVMakeRectWithAspectRatioInsideRect(
image.size,
CGRect(origin: CGPointZero, size: maxSize)
).size
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
image.drawInRect(CGRect(origin: CGPointZero, size: newSize))
let scaled = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return scaled
}
编辑:这是我在项目中使用的UIImage
的扩展名:
extension UIImage {
/**
Returns an scaled version of self that fits within the provided bounding box.
It retains aspect ratio, and also retains the rendering mode.
- parameter size: The target size, in point
- parameter scale: Optional target scale. If omitted, uses the scale of input image
- returns: A scaled image
*/
func imageFittingSize(size: CGSize, scale: CGFloat? = nil) -> UIImage {
let newSize = AVMakeRectWithAspectRatioInsideRect(self.size, CGRect(origin: CGPointZero, size: size)).size
UIGraphicsBeginImageContextWithOptions(newSize, false, scale ?? self.scale)
self.drawInRect(CGRect(origin: CGPointZero, size: newSize))
let scaled = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return scaled.imageWithRenderingMode(renderingMode)
}
}
你可以像这样的图像调用它:
let maxSize = CGSize(width: text.frame.size.width - 10, height: 600.0)
let scaled = image.imageFittingSize(maxSize)