Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rendering small CIImage centered in MTKView

I'm rendering a CIImage to MTKView and the image is smaller than the drawable.

let centered = image.transformed(by: CGAffineTransform(translationX: (view.drawableSize.width - image.extent.width) / 2, y: (view.drawableSize.height - image.extent.height) / 2))
context.render(centered, to: drawable.texture, commandBuffer: buffer, bounds: centered.extent, colorSpace: CGColorSpaceCreateDeviceRGB())

I'd expect the code above to render the image in the center of the view, but the image is positioned at origin instead.

Here's the repo illustrating the problem: https://github.com/truemetal/centered-render-of-ciimage-to-mtkview

Before blaming Metal or CoreImage I'd like to make sure I'm not doing something wrong.

I'd appreciate a link to the documentation that says I can't do something like that.

problem screenshot

I can workaround this by compositing the image over another one that would be exactly the size of the drawable like so, but I'm still interested in why exactly the code above does not work.

let centered = image.transformed(by: CGAffineTransform(translationX: (view.drawableSize.width - image.extent.width) / 2, y: (view.drawableSize.height - image.extent.height) / 2))
let background = CIImage(color: .white).cropped(to: CGRect(origin: .zero, size: view.drawableSize))
let preparedImage = centered.composited(over: background)
self.context.render(preparedImage, to: drawable.texture, commandBuffer: buffer, bounds: preparedImage.extent, colorSpace: CGColorSpaceCreateDeviceRGB())
like image 772
Dannie P Avatar asked Jan 28 '26 10:01

Dannie P


1 Answers

This is most curious. If you use the "new" CIRenderDestination API instead of context.render(…) it actually works:

let destination = CIRenderDestination(width: Int(view.drawableSize.width),
                                      height: Int(view.drawableSize.height),
                                      pixelFormat: view.colorPixelFormat,
                                      commandBuffer: buffer,
                                      mtlTextureProvider: { () -> MTLTexture in
                                          return drawable.texture
                                      })
try! self.context.startTask(toRender: centered, to: destination)

I don't know why, but context.render(…) doesn't seem to respect the translation of the image or the given bounds. Maybe someone else knows more...

like image 179
Frank Schlegel Avatar answered Jan 31 '26 00:01

Frank Schlegel