之前笔者已经分享过旋转图片的算法给大家了,那接下来碰到的问题就是,当时只做了ImageView的旋转,旋转一定角度之后,我该怎样剪切最大的等比内切矩形?要解决的问题如下:
第一,怎样旋转画布上的图片
毫无疑问,我第一反应就是使用CoreGraphics,初步的想法是将图片画在画布上,然后和imageView做相同的仿射变换,但是大家都知道,CG的变换都是针对画布的,而不是图片,那是不是就相当于画布要和图片做相反的动作?
第二,画布大小
要保证剪切后的图片和之前的图像大小相同,那画布的大小即图片的大小
第三,图片的大小
大家应该都知道,系统在旋转功能上不单单是旋转,还做了一定程度的缩放,需要我们重新计算旋转之后的大小
图片旋转的倍数我是这样计算的:
func imageViewScale() -> CGFloat {
let scaleX = self.imageView.frame.size.width/self.imageView.bounds.size.width
let scaleY = self.imageView.frame.size.height/self.imageView.bounds.size.height
let scale = fabsf(Float(scaleX)) > fabsf(Float(scaleY)) ? scaleX : scaleY
return scale
}
OK,那结合以上三点,我们总结代码如下:
// 计算旋转后图片的大小
let size = CGSize(width: imageSize.width * self.imageViewScale(), height: imageSize.height * self.imageViewScale())
// 创建画布
let context = CGContext.init(data: nil,
width: Int(imageSize.width),
height: Int(imageSize.height),
bitsPerComponent: sourceImage.bitsPerComponent,
bytesPerRow: 0,
space: sourceImage.colorSpace!,
bitmapInfo: sourceImage.bitmapInfo.rawValue)
context?.setFillColor(UIColor.clear.cgColor)
context?.fill(CGRect(origin: CGPoint.zero, size: imageSize))
context?.concatenate(transform.inverted())
context?.draw(sourceImage, in: CGRect(x: 0,
y: 0,
width: size.width,
height: size.height))
let result = context?.makeImage()
UIGraphicsEndImageContext()
坑还在后面。。上述代码写完之后发现,图片转到图像外面去了。。。仔细看看角度好想对,但是,并不是围绕图片中心转的,而是围绕左上角转动的,Quartz2D就是这样的。。。。那如何解决呢,偶然google到一个前辈的分享,三步走,如何走看下图:
也就是说,先将画布的anchorPoint向右向下移到中心位置,旋转之后,再将画布移回到原位置。
最终代码如下:
// 计算旋转后图片的大小
let size = CGSize(width: imageSize.width * self.imageViewScale(), height: imageSize.height * self.imageViewScale())
// 创建画布
let context = CGContext.init(data: nil,
width: Int(imageSize.width),
height: Int(imageSize.height),
bitsPerComponent: sourceImage.bitsPerComponent,
bytesPerRow: 0,
space: sourceImage.colorSpace!,
bitmapInfo: sourceImage.bitmapInfo.rawValue)
context?.setFillColor(UIColor.clear.cgColor)
context?.fill(CGRect(origin: CGPoint.zero, size: imageSize))
// quartz旋转以左上角为中心,so 将画布移到右下角,旋转之后再向上移到原来位置
context?.translateBy(x: imageSize.width / 2, y: imageSize.height / 2)
context?.concatenate(transform.inverted())
context?.translateBy(x: -size.width / 2, y: -size.height / 2)
context?.draw(sourceImage, in: CGRect(x: 0,
y: 0,
width: size.width,
height: size.height))
let result = context?.makeImage()
UIGraphicsEndImageContext()
本文参考文章如下:
Quartz2D 图像处理