Проблемы с 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() позволяет постепенно накапливать рисование. Надеюсь, это поможет кому-то в какой-то момент.

Другие вопросы по тегам