我试图通过按下按钮将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