我写了一个 rgbToHSV cikernel 来转换图像中的像素;但是,它无法正常工作。我已将其范围缩小到 RGB 值在此过程中被扭曲的事实。
为了简化我的代码,我将其更改为一个简单的通过过滤器。
我已经传递了 1280 x 720 图像的图像,这些图像都是一种颜色,然后在它通过 cikernel 之前和之后在 (100, 100) v 位置采样像素颜色。
结果如下:
红色之前:pixelColor :: rgba:1.0:0.0:0.0:1.0 之后:pixelColor :: rgba:1.0:0.07450980392156863:0.0:1.0
之前的绿色:pixelColor :: rgba:0.0:1.0:0.0:1.0 之后:pixelColor :: rgba:0.0:0.984313725490196:0.0:1.0
蓝色之前:pixelColor :: rgba:0.0:0.0:1.0:1.0 之后:pixelColor :: rgba:0.0:0.1803921568627451:1.0:1.0
如您所见,红色和绿色略有失真,但蓝色严重失真。
我已经保存了输出文件并检查了颜色,过滤器肯定会改变颜色。
非常感谢任何关于为什么简单的直通会改变颜色的见解。
简化的直通滤波器:
kernel vec4 rgbToHsv( __sample rgb) {
return rgb;
}
这是使用 cikernel 的 CIFilter:
class RgbToHsvFilter: CIFilter {
@objc dynamic var inputImage: CIImage?
private lazy var kernel: CIColorKernel? = {
guard let path = Bundle.main.path(forResource: "RgbToHsv", ofType: "cikernel"),
let code = try? String(contentsOfFile: path) else { fatalError("Failed to load RgbToHsv.cikernel from bundle") }
let kernel = CIColorKernel(source: code)
return kernel
}()
override public var outputImage: CIImage! {
get {
if let inputImage = self.inputImage {
let args = [inputImage as AnyObject]
return self.kernel?.apply(extent: inputImage.extent, arguments: args)
} else {
return nil
}
}
}
}
调用过滤器
let rgbToHsvFilter = RgbToHsvFilter()
let currentCI = CIImage(cgImage: colorImage!.cgImage!)
rgbToHsvFilter.setValue(currentCI, forKey: kCIInputImageKey)
if let hsvImage = rgbToHsvFilter.outputImage {
if let image = cgImage(from: hsvImage) {
let newImage = UIImage(cgImage: image as! CGImage)
let _ = newImage.getPixelColor(pos: pixelPoint)
//UIImageWriteToSavedPhotosAlbum(newImage, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)
}
}
}
CGPoint 设置为 (100, 100) 的 getPixelColor 方法。我认为这个问题可能在这里发生,因为打印出来的颜色可能存在误传,但我检查了实际的输出图像,并且过滤器正在改变图像颜色:
func getPixelColor(pos: CGPoint) -> UIColor {
let pixelData = self.cgImage!.dataProvider!.data
let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)
let pixelInfo: Int = ((Int(self.size.width) * Int(pos.y)) + Int(pos.x)) * 4
let r = CGFloat(data[pixelInfo]) / CGFloat(255.0)
let g = CGFloat(data[pixelInfo+1]) / CGFloat(255.0)
let b = CGFloat(data[pixelInfo+2]) / CGFloat(255.0)
let a = CGFloat(data[pixelInfo+3]) / CGFloat(255.0)
print("pixelColor :: rgba : \(r) : \(g) : \(b) : \(a)")
return UIColor(red: r, green: g, blue: b, alpha: a)
}
和 cgImage(已编辑):
func cgImage(from ciImage: CIImage) -> CGImage? {
let context = CIContext(options: nil)
return context.createCGImage(ciImage, from: ciImage.extent)
}