Reputation: 10776
I know that when using the following snippet to create images and assign them to a view's layer's contents, the render block is automatically executed again when the view's backing properties changed, i.e. the window was moved to or from a retina display.
[NSImage imageWithSize:size flipped:NO drawingHandler:^BOOL(NSRect rect) {
CGContextRef const context = NSGraphicsContext.currentContext.graphicsPort;
....
return YES;
}];
Inside this rendering block, I am trying to vertically center another NSImage. I would like this to look as centered as possible on high resolution displays, but not blurry on non-retina screens. Hence I would like to know if there's any way to find out what contentScaleFactor the image is being rendered with.
This should really be straightforward, but even after hours of trying and searching the internet I have not found a way to find out whether the image is being rendered for a retina screen or not.
Upvotes: 2
Views: 1451
Reputation: 90521
From the High Resolution Guidelines for OS X: APIs for Supporting High Resolution — Getting Scale Information:
CGContextRef
The preferred way to get the scaling information for a CGContext object is to call the conversion function
CGContextConvertRectToDeviceSpace
:deviceRect = CGContextConvertRectToDeviceSpace(context, userRect);
Then you can divide
deviceRect.size.height
byuserRect.size.height
. This works for both implicitly scaled window contexts and explicitly scaled bitmap contexts.
I don't actually think you should compute the scale, though. I think you should convert from user space to device space both the rect
parameter to your drawing handler and a rect constructed with an arbitrary origin (NSZeroPoint
will do) and with the size of the image that you're trying to center. Adjust the origin of the latter to mathematically center it within the former in device space. Integralize the result using NSIntegralRectWithOptions()
. Then, convert it back to user space using CGContextConvertRectToUserSpace()
. Draw the image into the resulting rect.
Upvotes: 4
Reputation: 10776
I figured it can be achieved via
CGFloat const scale = CGBitmapContextGetWidth(context) / rect.size.width;
However, I don't think this is a nice solution and there should/has to be something better.
Upvotes: 0