NSImage的drawingHandler和retina屏幕

时间:2014-10-08 18:29:59

标签: retina-display nsimage

我知道当使用以下代码段创建图像并将其分配给视图的图层内容时,当视图的支持属性发生变化时,渲染块会自动再次执行,即窗户被移动到视网膜显示器或从视网膜显示器移开。

[NSImage imageWithSize:size flipped:NO drawingHandler:^BOOL(NSRect rect) {
    CGContextRef const context = NSGraphicsContext.currentContext.graphicsPort;
    ....
    return YES;
}];

在这个渲染块中,我试图垂直居中另一个NSImage。我希望这在高分辨率显示器上看起来尽可能居中,但在非视网膜屏幕上不模糊。因此,我想知道是否有办法找出正在渲染图像的contentScaleFactor。

这应该是直截了当的,但即使经过几个小时的尝试和搜索互联网,我也没有找到方法来确定图像是否正在为视网膜屏幕呈现。

2 个答案:

答案 0 :(得分:2)

来自High Resolution Guidelines for OS X: APIs for Supporting High Resolution — Getting Scale Information

  

CGContextRef

     

获取CGContext的缩放信息的首选方法   对象是调用转换函数   CGContextConvertRectToDeviceSpace

deviceRect = CGContextConvertRectToDeviceSpace(context, userRect);
     

然后你可以将deviceRect.size.height除以   userRect.size.height。这适用于隐式缩放窗口   上下文和显式缩放的位图上下文。

但是,我实际上并不认为你应该计算比例。我认为你应该从用户空间转换到设备空间rect参数到你的绘图处理程序和用任意原点构造的矩形(NSZeroPoint都会这样做)以及你的图像大小重新尝试居中。调整后者的原点以数学方式将其置于设备空间中的前者中。使用NSIntegralRectWithOptions()对结果进行积分。然后,使用CGContextConvertRectToUserSpace()将其转换回用户空间。将图像绘制到生成的矩形中。

答案 1 :(得分:0)

我认为可以通过

实现

CGFloat const scale = CGBitmapContextGetWidth(context) / rect.size.width;

但是,我不认为这是一个很好的解决方案,应该/必须有更好的东西。