Проблемы с CIImageAccumulator из текстуры MTKView
Я хочу захватить вывод MTKView через текстуру вида в CIImageAccumulator для достижения эффекта постепенного наращивания рисования. Проблема в том, что аккумулятор, кажется, портит цвет / альфа / цветовое пространство оригинала, как показано ниже:
На изображении выше способ захвата более темного вида мазка кисти - через свойство currentDrawable.texture представления:
lastSubStrokeCIImage = CIImage(mtlTexture: self.currentDrawable!.texture, options: nil)!.oriented(CGImagePropertyOrientation.downMirrored)
subStrokeUIView.image = UIImage(ciImage: lastSubStrokeCIImage)
Теперь, когда я возьму то же изображение и передам его в CIIAcumulator для дальнейшей обработки (я делаю это только один раз для каждого сегмента чертежа), результат будет выглядеть более ярким, показанным в верхней части вложения:
lazy var ciSubCurveAccumulator: CIImageAccumulator =
{
[unowned self] in
return CIImageAccumulator(extent: CGRect(x: 0, y: 0, width: self.frame.width * self.contentScaleFactor, height: self.frame.height * self.window!.screen.scale ) , format: kCIFormatBGRA8)
}()!
ciSubCurveAccumulator.setImage(lastSubStrokeCIImage)
strokeUIView.image = UIImage(ciImage: ciSubCurveAccumulator.image())
Я пытался использовать различные форматы kCIF в определении CIImageAccumulator, но все безрезультатно. Что делает CIImageAccumulator, чтобы связываться с оригиналом, и как я могу это исправить? Обратите внимание, что я намерен использовать ciSubCurveAccumulator для постепенного создания непрерывного мазка постоянного цвета. Для простоты вопроса я не показываю накопительную часть. Эта проблема останавливает меня на пути.
Любые предложения будут любезно оценены
1 ответ
Проблема сводилась к двум вещам: во-первых, мне нужно было настроить MTLRenderPipelineDescriptor() для композитного композитора, а во-вторых, мне нужно было установить введение CIFilter для хранения промежуточного композитинга над накапливающимся CIImageAccumulator. Этот CIFilter также необходимо настроить для CIOverCompositing. Ниже приведен фрагмент кода, который охватывает все вышеперечисленное:
lazy var ciSubCurveAccumulator: CIImageAccumulator =
{
[unowned self] in
return CIImageAccumulator(extent: CGRect(x: 0, y: 0, width: self.frame.width * self.contentScaleFactor, height: self.frame.height * self.window!.screen.scale ) , format: kCIFormatBGRA8)
}()! // set up CIImageAccumulator
let lastSubStrokeCIImage = CIImage(mtlTexture: self.currentDrawable!.texture, options: nil)!.oriented(CGImagePropertyOrientation.downMirrored)
let compositeFilter : CIFilter = CIFilter(name: "CISourceOverCompositing")!
compositeFilter.setValue(lastSubStrokeCIImage, forKey: kCIInputImageKey) // foreground image
compositeFilter.setValue(ciSubCurveAccumulator.image(), forKey: kCIInputBackgroundImageKey) // background image
let bboxChunkSubCurvesScaledAndYFlipped = CGRect(...) // capture the part of the texture that was drawn to
ciSubCurveAccumulator.setImage(compositeFilter.value(forKey: kCIOutputImageKey) as! CIImage, dirtyRect: bboxChunkSubCurvesScaledAndYFlipped) // comp bbox with latest updates
Заключение вышеупомянутого фрагмента кода в draw() позволяет постепенно накапливать рисование. Надеюсь, это поможет кому-то в какой-то момент.