如何将LUT png用于CIColorCubefilter?

我想在Swift中使用查找表png( 示例 )作为CIColorCubefilter的颜色立方体数据。 所有我尝试(和发现)到目前为止是一个计算的颜色立方体的例子,在这个例子中 。

我怎样才能读取一个PNG作为查找数据?

我现在使用这个和这个项目来调整Swift的Objective-C实现:

 func colorCubeFilterFromLUT(imageName : NSString) -> CIFilter? { let kDimension : UInt = 64 let lutImage = UIImage(named: imageName)!.CGImage let lutWidth = CGImageGetWidth(lutImage!) let lutHeight = CGImageGetHeight(lutImage!) let rowCount = lutHeight / kDimension let columnCount = lutWidth / kDimension if ((lutWidth % kDimension != 0) || (lutHeight % kDimension != 0) || (rowCount * columnCount != kDimension)) { NSLog("Invalid colorLUT %@", imageName); return nil } let bitmap = self.createRGBABitmapFromImage(lutImage) let size = Int(kDimension) * Int(kDimension) * Int(kDimension) * sizeof(Float) * 4 let data = UnsafeMutablePointer<Float>(malloc(UInt(size))) var bitmapOffset : Int = 0 var z : UInt = 0 for (var row: UInt = 0; row < rowCount; row++) { for (var y: UInt = 0; y < kDimension; y++) { var tmp = z for (var col: UInt = 0; col < columnCount; col++) { for (var x: UInt = 0; x < kDimension; x++) { let alpha = Float(bitmap[Int(bitmapOffset)]) / 255.0 let red = Float(bitmap[Int(bitmapOffset+1)]) / 255.0 let green = Float(bitmap[Int(bitmapOffset+2)]) / 255.0 let blue = Float(bitmap[Int(bitmapOffset+3)]) / 255.0 var dataOffset = Int(z * kDimension * kDimension + y * kDimension + x) * 4 data[dataOffset] = red data[dataOffset + 1] = green data[dataOffset + 2] = blue data[dataOffset + 3] = alpha bitmapOffset += 4 } z++ } z = tmp } z += columnCount } let colorCubeData = NSData(bytesNoCopy: data, length: size, freeWhenDone: true) // create CIColorCube Filter var filter = CIFilter(name: "CIColorCube") filter.setValue(colorCubeData, forKey: "inputCubeData") filter.setValue(kDimension, forKey: "inputCubeDimension") return filter } func createRGBABitmapFromImage(inImage: CGImage) -> UnsafeMutablePointer<Float> { //Get image width, height let pixelsWide = CGImageGetWidth(inImage) let pixelsHigh = CGImageGetHeight(inImage) // Declare the number of bytes per row. Each pixel in the bitmap in this // example is represented by 4 bytes; 8 bits each of red, green, blue, and // alpha. let bitmapBytesPerRow = Int(pixelsWide) * 4 let bitmapByteCount = bitmapBytesPerRow * Int(pixelsHigh) // Use the generic RGB color space. let colorSpace = CGColorSpaceCreateDeviceRGB() // Allocate memory for image data. This is the destination in memory // where any drawing to the bitmap context will be rendered. let bitmapData = malloc(CUnsignedLong(bitmapByteCount)) // bitmap let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue) // Create the bitmap context. We want pre-multiplied RGBA, 8-bits // per component. Regardless of what the source image format is // (CMYK, Grayscale, and so on) it will be converted over to the format // specified here by CGBitmapContextCreate. let context = CGBitmapContextCreate(bitmapData, pixelsWide, pixelsHigh, 8, UInt(bitmapBytesPerRow), colorSpace, bitmapInfo) let rect = CGRect(x:0, y:0, width:Int(pixelsWide), height:Int(pixelsHigh)) // Draw the image to the bitmap context. Once we draw, the memory // allocated for the context for rendering will then contain the // raw image data in the specified color space. CGContextDrawImage(context, rect, inImage) // Now we can get a pointer to the image data associated with the bitmap // context. // var data = CGBitmapContextGetData(context) // var dataType = UnsafeMutablePointer<Float>(data) // return dataType var convertedBitmap = malloc(UInt(bitmapByteCount * sizeof(Float))) vDSP_vfltu8(UnsafePointer<UInt8>(bitmapData), 1, UnsafeMutablePointer<Float>(convertedBitmap), 1, vDSP_Length(bitmapByteCount)) free(bitmapData) return UnsafeMutablePointer<Float>(convertedBitmap) } 

也看到这个答案。

虽然它与您所链接的LUT图像不完全相同,但Cocoa的CocoaLUT (我的一维和三维LUT框架)可以读取和写入3种不同types的LUT图像 。

当我第一次开始制作CocoaLUT并编写基于图像的LUT读写器时,我不知道如何在Cocoa中做低级别的位图图像工作。 我只是使用了NSBitmapImageRep,这意味着如果您需要在iOS中执行此操作,那么您运气不好,直到我决定回头修改它以与Core Graphics一起工作,并知道我现在知道的内容。

如果您正在为Mac应用程序编写此应用程序,则应该可以(在Swift中)执行以下操作:

 let imageLUT = LUT3D(fromURL:NSURL.fileURLWithPath("/path/to/image.tiff"), error: nil) let cubeFilter = imageLUT.coreImageFilterWithCurrentColorSpace() 

如果你需要首先生成一个空白或“身份”LUT图像来执行分级,你应该(在Swift中):

 let identity33 = LUT3D(identityOfSize: 33, inputLowerBound: 0, inputUpperBound: 1); let success = identity33.writeToURL(NSURL.fileURLWithPath("/path/to/output.tiff"), atomically: true, formatterID: "unwrappedCube", options: nil, conformLUT: true) 

请注意,您需要在整个TIFF文件中执行此操作! 同样,如果我终于可以解决这个问题,那么推广Core Graphics的代码将会解决所有这些问题。