我已经写了一个rgbToHSV cikernel来转换图像中的像素;然而,它不能正常工作。我已经缩小了范围,因为RGB值在这个过程中被扭曲了。
为了简化代码,我将其更改为一个简单的直通过滤器。
我已经传递了1280x720的图像,这些图像都是一种颜色,然后在它通过cikernel之前和之后,在位置(100,100)上采样像素颜色。
结果如下:
前红色:像素颜色::rgba : 1.0 : 0.0 : 0.0 : 1.0之后: pixelColor ::rgba : 1.0 : 0.07450980392156863 : 0.0 : 1.0
绿色之前:像素颜色::rgba : 0.0 : 1.0 : 0.0 : 1.0之后: pixelColor ::rgba : 0.0 : 0.984313725490196 : 0.0 : 1.0
蓝色之前:像素颜色::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)
}发布于 2020-09-19 14:59:32
因此,cgImage方法中的CIContext未正确初始化。
下面是修正后的方法:
func cgImage(from ciImage: CIImage) -> CGImage? {
let context = CIContext(options: [CIContextOption.workingColorSpace: kCFNull!])
return context.createCGImage(ciImage, from: ciImage.extent, format: .RGBA8, colorSpace: CGColorSpace.init(name: CGColorSpace.sRGB)!)
}https://stackoverflow.com/questions/63853752
复制相似问题