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

时间:2018-04-23 04:35:09

标签: swift image colors lookup-tables ciimage

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

当我将filter-name更改为sth时。不同于:“CIColorCube”,应用程序甚至崩溃并显示错误消息:“在解开可选值时意外发现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!)
}

1 个答案:

答案 0 :(得分:0)

请在IBAction func filterRetro

中添加此代码
false

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

[编辑]

inputImage.applyingFilter(&#34; name&#34;)方法正在调用CIFilter.init(name)。对于哪个医生说,

  

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

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

 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)
            }

试试这个。

感谢, Ĵ