Я написал ядро rgbToHSV для преобразования пикселей в изображениях; однако он работает некорректно. Я сузил его до того факта, что значения RGB искажаются по пути.
Чтобы упростить свой код, я изменил его на простой сквозной фильтр.
Я передал изображения 1280 x 720 изображений одного цвета, а затем произвел выборку цветов пикселей в позиции (100, 100) v до и после прохождения через cikernel.
Вот результаты:
Красный перед: 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;
}
Вот CIFilter, который использует cikernel:
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)
}
}
}
метод getPixelColor, где для CGPoint установлено значение (100, 100). Я думал, что проблема может возникать здесь как возможное искажение в заявлении печати выходящего цвета, но я проверил фактические выходные изображения, и фильтр изменяет цвета изображения:
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)
}
linear_to_srgb
илиsrgb_to_linear
- person SPatel   schedule 12.09.2020cgImage(from: hsvImage)
? - person Frank Schlegel   schedule 12.09.2020CGImage
сcreateCGImage(ciImage, from: ciImage.extent, colorSpace: CGColorspace(name: CGColorSpace.sRGB)!)
и посмотреть, изменится ли это? - person Frank Schlegel   schedule 14.09.2020