裁剪CIImage

时间:2016-11-24 18:00:36

标签: ios swift ios10 ciimage

我有一个带UIImage的课程,用它初始化CIImage

workingImage = CIImage.init(image: baseImage!)

然后使用图像从中切出3个3x3模式的9个相邻正方形 - 循环:

for x in 0..<3
    {
        for y in 0..<3
        {

            croppingRect = CGRect(x: CGFloat(Double(x) * sideLength + startPointX),
                                  y: CGFloat(Double(y) * sideLength + startPointY),
                                  width: CGFloat(sideLength),
                                  height: CGFloat(sideLength))
            let tmpImg = (workingImage?.cropping(to: croppingRect))!
        }
    }

那些tmpImgs被插入到一个表中并在以后使用,但除此之外。

此代码适用于IOS 9IOS 10模拟器,但实际的 IOS 10设备上 。产生的图像要么都是空的,要么其中一个就像它应该是的一半,其余的都是空的。

这不是应该在IOS 10中完成的吗?

2 个答案:

答案 0 :(得分:3)

问题的核心是通过CIImage并不是裁剪UIImage的方法。首先,从CIImage回到UIImage是一件复杂的事情。另一方面,整个往返都是不必要的。

如何裁剪

要裁剪图像,请创建所需裁剪尺寸的图像图形上下文,并在UIImage上调用draw(at:)以在相对于图形上下文的所需点处绘制它,以便图像的所需部分落下进入上下文。现在提取生成的新图像并关闭上下文。

为了演示,我将裁剪到你想要裁剪的三分之一的一个,即右下角的第三个:

let sz = baseImage.size
UIGraphicsBeginImageContextWithOptions(
    CGSize(width:sz.width/3.0, height:sz.height/3.0), 
    false, 0)
baseImage.draw(at:CGPoint(x: -sz.width/3.0*2.0, y: -sz.height/3.0*2.0))
let tmpImg = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

原始图片(baseImage):

enter image description here

裁剪后的图片(tmpImg):

enter image description here

其他部分完全平行。

答案 1 :(得分:1)

Core Image的坐标系与UIKit不匹配,因此需要镜像rect。

因此,在您的特定情况下,您需要:

var ciRect = croppingRect
ciRect.origin.y = workingImage!.extent.height - ciRect.origin.y - ciRect.height
let tmpImg = workingImage!.cropped(to: ciRect)

这绝对适用于iOS 10 +。

在更一般的情况下,我们将创建一个UIImage扩展,它涵盖两个可能的坐标系,并且比draw(at:)快得多:

extension UIImage {
    /// Return a new image cropped to a rectangle.
    /// - parameter rect:
    /// The rectangle to crop.
    open func cropped(to rect: CGRect) -> UIImage {
        // a UIImage is either initialized using a CGImage, a CIImage, or nothing
        if let cgImage = self.cgImage {
            // CGImage.cropping(to:) is magnitudes faster than UIImage.draw(at:)
            if let cgCroppedImage = cgImage.cropping(to: rect) {
                return UIImage(cgImage: cgCroppedImage)
            } else {
                return UIImage()
            }
        }
        if let ciImage = self.ciImage {
            // Core Image's coordinate system mismatch with UIKit, so rect needs to be mirrored.
            var ciRect = rect
            ciRect.origin.y = ciImage.extent.height - ciRect.origin.y - ciRect.height
            let ciCroppedImage = ciImage.cropped(to: ciRect)
            return UIImage(ciImage: ciCroppedImage)
        }
        return self
    }
}

我为此制作了一个广告连播,因此源代码位于https://github.com/Coeur/ImageEffects/blob/master/SwiftImageEffects/ImageEffects%2Bextensions.swift