如何将LUT(从.png)应用到图像? (Swift + Xcode)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将LUT(从.png)应用到图像? (Swift + Xcode)相关的知识,希望对你有一定的参考价值。

我试图通过按下按钮将LUT应用于图像。因为,我是编程新手,我主要复制代码并试图为我自己的项目修改它。我没有收到错误消息,但是当我尝试按下按钮时,对图像没有任何影响。

当我将filter-name更改为sth时。不同于:“CIColorCube”,应用程序甚至崩溃并显示错误消息:“在解开Optional值时意外发现nil”

My LUT Image that I am using. (size: 512x512)

func colorCubeFilterFromLUT(imageName : String) -> CIFilter? {

    let size = 512

    let lutImage    = UIImage(named: "LUT.png")!.cgImage
    let lutWidth    = lutImage!.width
    let lutHeight   = lutImage!.height
    let rowCount    = lutHeight / size
    let columnCount = lutWidth / size

    if ((lutWidth % size != 0) || (lutHeight % size != 0) || (rowCount * columnCount != size)) {
        NSLog("Invalid colorLUT %@", "LUT.png");
        return nil
    }

    let bitmap  = getBytesFromImage(image: UIImage(named: "LUT.png"))!
    let floatSize = MemoryLayout<Float>.size

    let cubeData = UnsafeMutablePointer<Float>.allocate(capacity: size * size * size * 4 * floatSize)
    var z = 0
    var bitmapOffset = 0

    for _ in 0 ..< rowCount {
        for y in 0 ..< size {
            let tmp = z
            for _ in 0 ..< columnCount {
                for x in 0 ..< size {

                    let alpha   = Float(bitmap[bitmapOffset]) / 255.0
                    let red     = Float(bitmap[bitmapOffset+1]) / 255.0
                    let green   = Float(bitmap[bitmapOffset+2]) / 255.0
                    let blue    = Float(bitmap[bitmapOffset+3]) / 255.0

                    let dataOffset = (z * size * size + y * size + x) * 4

                    cubeData[dataOffset + 3] = alpha
                    cubeData[dataOffset + 2] = red
                    cubeData[dataOffset + 1] = green
                    cubeData[dataOffset + 0] = blue
                    bitmapOffset += 4
                }
                z += 1
            }
            z = tmp
        }
        z += columnCount
    }

    let colorCubeData = NSData(bytesNoCopy: cubeData, length: size * size * size * 4 * floatSize, freeWhenDone: true)

    // create CIColorCube Filter
    let filter = CIFilter(name: "CIColorCube")
    filter?.setValue(colorCubeData, forKey: "inputCubeData")
    filter?.setValue(size, forKey: "inputCubeDimension")

    return filter
}


func getBytesFromImage(image:UIImage?) -> [UInt8]?
{
    var pixelValues: [UInt8]?
    if let imageRef = image?.cgImage {
        let width = Int(imageRef.width)
        let height = Int(imageRef.height)
        let bitsPerComponent = 8
        let bytesPerRow = width * 4
        let totalBytes = height * bytesPerRow

        let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Little.rawValue
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        var intensities = [UInt8](repeating: 0, count: totalBytes)

        let contextRef = CGContext(data: &intensities, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo)
        contextRef?.draw(imageRef, in: CGRect(x: 0.0, y: 0.0, width: CGFloat(width), height: CGFloat(height)))

        pixelValues = intensities
    }
    return pixelValues!
}

@IBAction func filterRetro(_ sender: Any) {
    let inputImage = CIImage(image: photo.image!)

    let filteredImage = inputImage?.applyingFilter("CIColorCube")

    let renderedImage = context.createCGImage(filteredImage!, from: (filteredImage?.extent)!)

    photo.image = UIImage(cgImage: renderedImage!)
}
答案

请在您的IBAction func filterRetro中添加此代码

 if let photoImage = photo.image  {
                let inputImage = CIImage(image: photoImage)
                let filteredImage = inputImage.applyingFilter("CIColorCube")
                let filteredExtent = filteredImage.extent

                /* hoping this will return a CGImage */
                let renderedImage = context.createCGImage(filteredImage, from: filteredExtent)
                photo.image =  UIImage(cgImage: renderedImage)
            }

解决了按钮按下操作中可选包装的问题。但不是整个代码。让我知道这是否有效。

[编辑]

inputImage.applyingFilter(“name”)方法正在调用CIFilter.init(name)。对于哪个医生说,

过滤器的名称。您必须确保名称拼写正确,否则您的应用程序将运行但不会生成任何输出图像。因此,您应该在调用此方法后检查是否存在过滤器。

我建议使用单独的变量来创建过滤器,如果过滤器存在,则只应用于图像。

let filter = CIFilter("CIColorCube")
if filter {
   let filteredImage = inputImage.applyingFilter("CIColorCube")
}

试试这个。

谢谢,J

以上是关于如何将LUT(从.png)应用到图像? (Swift + Xcode)的主要内容,如果未能解决你的问题,请参考以下文章

如何将本地 jpeg 或 png 图像文件加载到 iPhone 应用程序中?

如何将PNG图像从Jersey REST服务方法返回到浏览器

如何阅读Hald Clut图像?

Objective C - NodeJS - 如何将特定文件(不是图像)从 iOS 应用程序上传到服务器?

如何将 png/jpeg 文件集成到统一移动应用程序项目中

将图像拖到透明 png 后面