简体   繁体   English

如何在CGImage上进行垂直翻转?

[英]How to perform vertical flipping on CGImage?

Currently, I have the following color wheel implemented using the following code目前,我使用以下代码实现了以下色轮

class ColorWheelPalette: UIView {
    var cgImage: CGImage?
    
    override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else {return}

        if self.cgImage == nil {
            // https://stackoverflow.com/a/54819655/72437
            let filter = CIFilter(name: "CIHueSaturationValueGradient", parameters: [
                "inputColorSpace": CGColorSpaceCreateDeviceRGB(),
                "inputDither": 0,
                "inputRadius": 160,
                "inputSoftness": 0,
                "inputValue": 1
            ])!
            
            let ciImage = filter.outputImage!
            let ciContext = CIContext(options: nil)
            self.cgImage = ciContext.createCGImage(ciImage, from: ciImage.extent)
        }
        
        context.draw(cgImage!, in: rect)
    }
}

It looks as following它看起来如下

在此处输入图像描述

However, the output image is not what I desire.但是,output 图像不是我想要的。 I want to green color region stay on the top.我想让绿色区域保持在顶部。 Hence, I do a quick vertical flipping using the following code因此,我使用以下代码进行快速垂直翻转

class ColorWheelPalette: UIView {
    var cgImage: CGImage?
    
    override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else {return}

        if self.cgImage == nil {
            // https://stackoverflow.com/a/54819655/72437
            let filter = CIFilter(name: "CIHueSaturationValueGradient", parameters: [
                "inputColorSpace": CGColorSpaceCreateDeviceRGB(),
                "inputDither": 0,
                "inputRadius": 160,
                "inputSoftness": 0,
                "inputValue": 1
            ])!
            
            let ciImage = filter.outputImage!
            let ciContext = CIContext(options: nil)
            self.cgImage = ciContext.createCGImage(ciImage, from: ciImage.extent)
        }
        
        context.saveGState()
        
        // Flip vertically
        context.translateBy(x: 0, y: rect.height)
        context.scaleBy(x: 1.0, y: -1.0)
        
        context.draw(cgImage!, in: rect)
        
        context.restoreGState()
    }
}

The above code achieve what I want (green region at the top)上面的代码实现了我想要的(顶部的绿色区域)

在此处输入图像描述


However, for performance optimisation purpose, instead of having perform translate and scale transformation operations each time,但是,出于性能优化的目的,不是每次都执行平移和缩放转换操作,

is there a way to perform such vertical flipping on the self.cgImage directly for just one-time?有没有办法直接在self.cgImage上执行这种垂直翻转一次?

So that the ideal code would look like the following这样理想的代码将如下所示

class ColorWheelPalette: UIView {
    ...
    
    override func draw(_ rect: CGRect) {
        ...

        if self.cgImage == nil {
            ...
            self.cgImage = ciContext.createCGImage(ciImage, from: ciImage.extent)
            
            // Question: Can we perform one-time vertical flipping on self.cgImage right here?
        }
        
        context.draw(cgImage!, in: rect)
    }
}

Just create an UIImage from your CGImage and draw it directly:只需从您的CGImage中创建一个UIImage并直接绘制它:

class ColorWheelPalette: UIView {
    var image: UIImage?
    override func draw(_ rect: CGRect) {
        if image == nil {
            guard
                let filter = CIFilter(name: "CIHueSaturationValueGradient", parameters: [
                "inputColorSpace": CGColorSpaceCreateDeviceRGB(),
                "inputDither": 0,
                "inputRadius": 160,
                "inputSoftness": 0,
                "inputValue": 1]),
                let ciImage = filter.outputImage,
                let cgImage = CIContext(options: nil)
                    .createCGImage(ciImage, from: ciImage.extent)
            else { return }
            let size = ciImage.extent.size
            let format = UIGraphicsImageRendererFormat.default()
            format.opaque = false
            image = UIGraphicsImageRenderer(size: size, format: format).image { ctx in
                var transform = CGAffineTransform(scaleX: 1, y: -1)
                transform = transform.translatedBy(x: 0, y: -size.height)
                ctx.cgContext.concatenate(transform)
                ctx.cgContext.draw(cgImage, in: CGRect(origin: .zero, size: size))
            }
        }
        image?.draw(in: rect)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM