美文网首页
继旋转图片后的剪切图片

继旋转图片后的剪切图片

作者: Aprilsky | 来源:发表于2017-04-27 15:21 被阅读76次

    之前笔者已经分享过旋转图片的算法给大家了,那接下来碰到的问题就是,当时只做了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 图像处理

    相关文章

      网友评论

          本文标题:继旋转图片后的剪切图片

          本文链接:https://www.haomeiwen.com/subject/xdagzttx.html