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



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

当我将过滤器名称更改为 sth. 不同于:"CIColorCube"时,该应用程序甚至崩溃并显示错误消息:"解开可选值时意外发现 nil"

我正在使用的 LUT 图像。(尺寸: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

相关内容

  • 没有找到相关文章

最新更新