在Swift中加快图像处理速度

在Swift中加快图像处理速度,swift,xcode,image-processing,uiimage,Swift,Xcode,Image Processing,Uiimage,我正在尝试应用下一个代码对从库中拍摄的图像进行着色: func zoeFilter() -> UIImage? { let brownColor = UIColor (red: 128/255, green: 0, blue: 0, alpha: 1) let colorRect = CGRect (origin: .zero, size: self.size) let renderer = UIGraphicsImageRenderer

我正在尝试应用下一个代码对从库中拍摄的图像进行着色:

func zoeFilter() -> UIImage? {
        let brownColor = UIColor (red: 128/255, green: 0, blue: 0, alpha: 1)
        let colorRect = CGRect (origin: .zero, size: self.size)

        let renderer = UIGraphicsImageRenderer (bounds: colorRect)

        let brownColoredImage = renderer.image { ctx in
            ctx.cgContext.setFillColor(greyColor.cgColor)
            ctx.fill(colorRect)
        }

        let outBrown0Image = renderer.image { ctx in
            ctx.cgContext.setFillColor(UIColor.white.cgColor)
            ctx.fill(colorRect)
            self.draw(in: colorRect, blendMode: .normal, alpha: 1)
            brownColoredImage.draw(in: colorRect, blendMode: .colorDodge, alpha: 1)
        }

        let outBrownImage = renderer.image { ctx in
            self.draw(in: colorRect, blendMode: .normal, alpha: 1)
            outBrown0Image.draw(in: colorRect, blendMode: .multiply, alpha: 1)
        }

        return outBrownImage
    }
但处理图像大约需要14秒,这对用户体验不是很好

你知道我怎样才能得到同样的结果,但加快图像处理

你有小费吗

提前谢谢

最终解决方案


最简单的方法是将这3个
renderer.image{…}
调用折叠为一个调用。您应该能够将第二个2次调用的内容移动到第一个调用中。这将产生巨大的性能差异

除此之外,你真的需要在一个全尺寸的图像上做这件事吗?如果没有,请在执行所有不需要的渲染之前,调整在渲染器上设置的大小

通常,当您试图以高性能的方式进行这样的过滤时,您会使用
CoreImage
。有了它,你可以以非常高的速度处理图像。比如60 fps,用于过滤实时视频

我先看看苹果的内置过滤器列表:

下面是如何使用过滤器的一个很好的示例:

如果您发现无法组合内置过滤器以获得效果,您可以编写自己的非常简单的金属背景过滤器:

你说得对!我使用UIGraphics专注于此,而关键点已改为CoreImage。我刚刚编辑了根据你的答案发布的最终代码。非常感谢你!很高兴我能帮忙!
func zoeFilter() -> UIImage? {
        let inImage = CIImage (image: self)

        let SRGBImage = inImage?.applyingFilter("CILinearToSRGBToneCurve")

        let brownColor = CIColor (red: 128/255, green: 0, blue: 0, alpha: 1)
        let colorRect = CGRect (origin: .zero, size: self.size)

        dynamic let colorFilter = CIFilter(name: "CIConstantColorGenerator")
        dynamic let colorizeFilter = CIFilter (name: "CIColorDodgeBlendMode")
        dynamic let multiplyFilter = CIFilter (name: "CIMultiplyBlendMode")

        colorFilter?.setValue(brownColor, forKey: kCIInputColorKey)
        let brownSolidImage = colorFilter?.outputImage?.cropped(to: colorRect)

        colorizeFilter?.setValue(SRGBImage, forKey: kCIInputBackgroundImageKey)
        colorizeFilter?.setValue(brownSolidImage, forKey: kCIInputImageKey)
        let outBrown0Image = colorizeFilter?.outputImage

        multiplyFilter?.setValue(SRGBImage, forKey: kCIInputBackgroundImageKey)
        multiplyFilter?.setValue(outBrown0Image, forKey: kCIInputImageKey)
        let outBrownImage = multiplyFilter?.outputImage

        let linearImage = outBrownImage?.applyingFilter("CISRGBToneCurveToLinear")

        let cgImage = CIContext().createCGImage(linearImage!, from: linearImage!.extent)
        return UIImage (cgImage: cgImage!)
    }