Скомпонуйте два CIImages и отобразите в проблеме UIImageView

У меня возникли проблемы с объединением двух изображений вместе с CIFilter. Что здесь происходит не так?

Приведенный ниже код создает UIImageView и добавляет его в представление, затем объединяет два изображения imageA и imageB с CIFilter и выводит композит в UIImageView.

Однако объединенное изображение не отображается в UIImageView, оно остается пустым.


Вопросы:

  1. Каков правильный код для отображения составного изображения в UIImageView?
  2. Есть ли более эффективный способ объединения двух изображений с помощью CIFilter?

Код:

    let imageView = UIImageView()
    imageView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)
    imageView.contentMode = .Center
    view.addSubview(imageView)

    let imageA = CIImage(image: UIImage(named:"imageA")!)
    let imageB = CIImage(image: UIImage(named:"imageB")!)
    let imageFilter = CIFilter(name: "CIAdditionCompositing")!

    imageFilter.setValue(imageA, forKey: kCIInputImageKey)
    imageFilter.setValue(imageB, forKey: kCIInputBackgroundImageKey)

    if let imageCombined = imageFilter.outputImage {
        let image = UIImage(CIImage: imageCombined)
        imageView.image = image
    }

person user4806509    schedule 18.12.2017    source источник
comment
Какую отладку вы сделали? Доходит ли этот код до строки, которая устанавливает свойство image представления изображения?   -  person rmaddy    schedule 18.12.2017
comment
@rmaddy Да, код работает со свойством изображения. Нет ошибок.   -  person user4806509    schedule 18.12.2017


Ответы (1)


У меня всегда были проблемы с прямыми UIImage ‹‹ >> CIImage преобразованиями. Если у вас есть фрейм/размер/протяженность, с которыми вы можете работать, я рекомендую использовать CIContext и сначала создать CGImage:

let ciContext = CIContext(options: nil)
let cgImg = ciContext.createCGImage(imageCombined, from: imageCombined.extent)
let uiImage = UIImage(cgImage: cgImg!)

Помните, что создание CIContext является «дорогостоящим», поэтому, если вам нужно сделать это для нескольких изображений, создайте одно и используйте его для всех рендерингов. Кроме того, если вы где-то используете GLKView, используйте его контекст.

Что касается вопроса № 2, ваш код выглядит нормально. Вы можете «объединить строки кода, но это не повлияет на производительность. CoreImage ничего не «обрабатывает», пока вы не вызовете outputImage фильтра.

person dfd    schedule 18.12.2017
comment
Спасибо @dfd. Я попробую в ближайшее время. Любая конкретная причина, по которой прямые преобразования UIImage ‹‹ ›› CIImage могут вызывать некоторые проблемы? Есть ли еще более оптимизированный способ объединения изображений, более эффективный для производительности? - person user4806509; 18.12.2017
comment
Честно говоря, я не знаю, почему прямое преобразование ненадежно. Я всегда использовал метод выше. Это, в сочетании с отображением вещей в GLKView, очень хорошо с точки зрения производительности. Вы можете использовать это (вместе с ползунками, прикрепленными к входным параметрам) для достижения рендеринга фильтра в реальном времени. Затем и только при необходимости конвертируйте в UIImage. Следует помнить одну вещь: CoreImage (и GLKViews) оптимизированы для использования графического процессора. Тестирование в симуляторе приведет к снижению производительности. Прежде чем думать, что у вас проблемы с производительностью, попробуйте на реальном устройстве. - person dfd; 18.12.2017
comment
Большое спасибо @dfd за все эти объяснения. - person user4806509; 18.12.2017