Мне снова нужна помощь в преобразовании моего приложения Android в iOS...
Как я упоминал в другом посте, приложение предназначено для обработки изображений и основано на ColorMatrix. Проблема в том, что Swift поддерживает (насколько мне известно...) только матрицу 4x4, а для яркости или контрастности я использую матрицу 5x5 в Android.
В Android это моя матрица:
Яркость:
float[] brightMatrix = {
1f, 0f, 0f, 0f, 32f,
0f, 1f, 0f, 0f, 32f,
0f, 0f, 1f, 0f, 32f,
0f, 0f, 0f, 1f, 0f,
0f, 0f, 0f, 0f, 1f};
Контраст:
float[] contMatrix = {
1.190f, 0f, 0f, 0f, -12.065f,
0f, 1.190f, 0f, 0f, -12.065f,
0f, 0f, 1.190f, 0f, -12.065f,
0f, 0f, 0f, 1f, 0f,
0f, 0f, 0f, 0f, 1f};
Но я действительно не знаю, как получить такие же результаты в Swift...
В случае яркости я попытался использовать этот код, разделив 32/255, чтобы получить значение 0,12549:
func zoeFilter() -> UIImage? {
let inImage = CIImage (image: self)
dynamic let brightFactor = CIFilter (name: "CIColorControls")
brightFactor?.setValue(inImage, forKey: kCIInputImageKey)
brightFactor?.setValue(0.12549, forKey: kCIInputBrightnessKey)
let brightImage = brightFactor?.outputImage
let cgImage = CIContext().createCGImage(brightImage!, from: brightImage!.extent)
return UIImage (cgImage: cgImage!)
}
Но результат совсем не тот... в iOS это как белый туман...
И говоря о контрасте, я нашел следующий код, но я не могу преобразовать матрицу Android только в значение здесь contFactor?.setValue(1, forKey: kCIInputContrastKey)
просто зная, что 1 равно нейтральному:
func chiaFilter() -> UIImage? {
let inImage = CIImage (image: self)
dynamic let contFactor = CIFilter (name: "CIColorControls")
contFactor?.setValue(inImage, forKey: kCIInputImageKey)
contFactor?.setValue(1, forKey: kCIInputContrastKey)
let contImage = contFactor?.outputImage
let cgImage = CIContext().createCGImage(contImage!, from: contImage!.extent)
return UIImage (cgImage: cgImage!)
}
С другой стороны, изменить экспозицию легко, потому что матрица в Android выглядит так:
float[] expMatrix = {
1.3f, 0f, 0f, 0f, 0f,
0f, 1.3f, 0f, 0f, 0f,
0f, 0f, 1.3f, 0f, 0f,
0f, 0f, 0f, 1f, 0f,
0f, 0f, 0f, 0f, 1f};
Итак, в Swift я могу использовать следующий код, получая точно такой же результат:
func liaFilter() -> UIImage? {
let inImage = CIImage (image: self)
dynamic let expoMatrix = CIFilter (name: "CIColorMatrix")
expoMatrix?.setDefaults()
expoMatrix?.setValue(inImage, forKey: kCIInputImageKey)
expoMatrix?.setValue(CIVector (x: 1.3, y: 0, z: 0, w: 0), forKey: "inputRVector")
expoMatrix?.setValue(CIVector (x: 0, y: 1.3, z: 0, w: 0), forKey: "inputGVector")
expoMatrix?.setValue(CIVector (x: 0, y: 0, z: 1.3, w: 0), forKey: "inputBVector")
expoMatrix?.setValue(CIVector (x: 0, y: 0, z: 0, w: 1), forKey: "inputAVector")
let expoImage = expoMatrix?.outputImage
let cgImage = CIContext().createCGImage(expoImage!, from: expoImage!.extent)
return UIImage (cgImage: cgImage!)
}
Это так запутанно... Я знаю... но было бы здорово, если бы у кого-нибудь была идея, как решить эти проблемы между Android и iOS.
Заранее спасибо!
ИЗДАНИЕ ПОСЛЕ ОТВЕТА ФРАНКА
Вот после применения фильтра с Android с помощью:
float[] brightMatrix = {
1f, 0f, 0f, 0f, 32f,
0f, 1f, 0f, 0f, 32f,
0f, 0f, 1f, 0f, 32f,
0f, 0f, 0f, 1f, 0f,
0f, 0f, 0f, 0f, 1f};
Вот то же изображение, применяющее фильтр с iOS, используя:
brightMatrix?.setValue(CIVector (x: 1, y: 0, z: 0, w: 0), forKey: "inputRVector")
brightMatrix?.setValue(CIVector (x: 0, y: 1, z: 0, w: 0), forKey: "inputGVector")
brightMatrix?.setValue(CIVector (x: 0, y: 0, z: 1, w: 0), forKey: "inputBVector")
brightMatrix?.setValue(CIVector (x: 0, y: 0, z: 0, w: 1), forKey: "inputAVector")
brightMatrix?.setValue(CIVector (x: 32.0/255.0, y: 32.0/255.0, z: 32.0/255.0, w: 0), forKey: "inputBiasVector")
ФИНАЛЬНОЕ РЕШЕНИЕ, РАБОТАЮЩЕЕ ПОСЛЕ ПРЕДЛОЖЕНИЯ ФРАНКА
func zoeFilter() -> UIImage? {
let inImage = CIImage (image: self)
dynamic let SRGBMatrix = CIFilter (name: "CILinearToSRGBToneCurve")
dynamic let brightMatrix = CIFilter (name: "CIColorMatrix")
dynamic let linearMatrix = CIFilter (name: "CISRGBToneCurveToLinear")
SRGBMatrix?.setValue(inImage, forKey: kCIInputImageKey)
let SRGBImage = SRGBMatrix?.outputImage
brightMatrix?.setDefaults()
brightMatrix?.setValue(SRGBImage, forKey: kCIInputImageKey)
brightMatrix?.setValue(CIVector (x: 1, y: 0, z: 0, w: 0), forKey: "inputRVector")
brightMatrix?.setValue(CIVector (x: 0, y: 1, z: 0, w: 0), forKey: "inputGVector")
brightMatrix?.setValue(CIVector (x: 0, y: 0, z: 1, w: 0), forKey: "inputBVector")
brightMatrix?.setValue(CIVector (x: 0, y: 0, z: 0, w: 1), forKey: "inputAVector")
brightMatrix?.setValue(CIVector (x: 32.0/255.0, y: 32.0/255.0, z: 32.0/255.0, w: 0), forKey: "inputBiasVector")
let brightImage = brightMatrix?.outputImage
linearMatrix?.setDefaults()
linearMatrix?.setValue(brightImage, forKey: kCIInputImageKey)
let linearImage = linearMatrix?.outputImage
let cgImage = CIContext().createCGImage(linearImage!, from: linearImage!.extent)
return UIImage (cgImage: cgImage!)
}
setDefaults
на фильтрах, если вы все равно установили все параметры (или у фильтра их нет). (2) Вы можете использовать ярлыкlet SRGBImage = inImage.applyingFilter("CILinearToSRGBToneCurve")
, чтобы сохранить несколько строк в каждой. - person Frank Schlegel   schedule 25.02.2020