Ускорение скорости обработки UIImage в Swift - PullRequest
0 голосов
/ 23 марта 2020

Я пытаюсь применить следующий код для раскрашивания изображения, взятого из галереи:

func zoeFilter() -> UIImage? {
        let brownColor = UIColor (red: 128/255, green: 0, blue: 0, alpha: 1)
        let colorRect = CGRect (origin: .zero, size: self.size)

        let renderer = UIGraphicsImageRenderer (bounds: colorRect)

        let brownColoredImage = renderer.image { ctx in
            ctx.cgContext.setFillColor(greyColor.cgColor)
            ctx.fill(colorRect)
        }

        let outBrown0Image = renderer.image { ctx in
            ctx.cgContext.setFillColor(UIColor.white.cgColor)
            ctx.fill(colorRect)
            self.draw(in: colorRect, blendMode: .normal, alpha: 1)
            brownColoredImage.draw(in: colorRect, blendMode: .colorDodge, alpha: 1)
        }

        let outBrownImage = renderer.image { ctx in
            self.draw(in: colorRect, blendMode: .normal, alpha: 1)
            outBrown0Image.draw(in: colorRect, blendMode: .multiply, alpha: 1)
        }

        return outBrownImage
    }

Но обработка изображения занимает около 14 секунд, что не очень хорошо для пользователя ...

Знаете ли вы, как получить такой же результат, но ускорить обработку изображения?

У вас есть совет?

Заранее спасибо!

ЗАКЛЮЧИТЕЛЬНОЕ РЕШЕНИЕ

func zoeFilter() -> UIImage? {
        let inImage = CIImage (image: self)

        let SRGBImage = inImage?.applyingFilter("CILinearToSRGBToneCurve")

        let brownColor = CIColor (red: 128/255, green: 0, blue: 0, alpha: 1)
        let colorRect = CGRect (origin: .zero, size: self.size)

        dynamic let colorFilter = CIFilter(name: "CIConstantColorGenerator")
        dynamic let colorizeFilter = CIFilter (name: "CIColorDodgeBlendMode")
        dynamic let multiplyFilter = CIFilter (name: "CIMultiplyBlendMode")

        colorFilter?.setValue(brownColor, forKey: kCIInputColorKey)
        let brownSolidImage = colorFilter?.outputImage?.cropped(to: colorRect)

        colorizeFilter?.setValue(SRGBImage, forKey: kCIInputBackgroundImageKey)
        colorizeFilter?.setValue(brownSolidImage, forKey: kCIInputImageKey)
        let outBrown0Image = colorizeFilter?.outputImage

        multiplyFilter?.setValue(SRGBImage, forKey: kCIInputBackgroundImageKey)
        multiplyFilter?.setValue(outBrown0Image, forKey: kCIInputImageKey)
        let outBrownImage = multiplyFilter?.outputImage

        let linearImage = outBrownImage?.applyingFilter("CISRGBToneCurveToLinear")

        let cgImage = CIContext().createCGImage(linearImage!, from: linearImage!.extent)
        return UIImage (cgImage: cgImage!)
    }

1 Ответ

1 голос
/ 23 марта 2020

Самое простое, что можно попробовать - это объединить эти 3 renderer.image { ... } звонки в один звонок. Вы должны быть в состоянии просто переместить содержимое вторых 2 вызовов в первый. Это должно иметь огромное значение для производительности.

Кроме того, вам действительно нужно сделать это на полноразмерном изображении с камеры? Если нет, отрегулируйте размер, установленный для рендерера, прежде чем выполнять все ненужные операции рендеринга.

Как правило, когда вы пытаетесь выполнить фильтрацию таким образом с высокой производительностью, вы должны использовать CoreImage. При этом вы можете обрабатывать изображения на очень высокой скорости. Как 60 кадров в секунду для фильтрации живого видео.

Я бы начал с просмотра встроенного списка фильтров Apple: https://developer.apple.com/library/archive/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html

Вот довольно хороший пример того, как использовать фильтр: https://www.hackingwithswift.com/articles/204/how-to-use-core-image-filters-the-type-safe-way

Если вы обнаружите, что не можете объединить встроенные фильтры для получения эффекта (-ов), вы всегда можете написать довольно простые фильтры на металлической основе. самостоятельно: https://flexmonkey.blogspot.com/2016/01/metal-kernel-functions-as-core-image.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...