防止CALayer renderInContext的抗锯齿

时间:2013-01-14 14:35:06

标签: ios calayer

我有一个非常简单的UIView,其中包含一些黑白UIImageView。如果我通过设备上的物理按钮截取屏幕截图,结果图像看起来与我看到的完全一样(如预期的那样) - 如果我在像素级别检查图像,它只是黑白图像。

但是,如果我使用以下代码片段以编程方式执行相同的操作,则生成的图像具有应用的抗锯齿功能 - 所有黑色像素都被微弱的灰色光环包围。我的原始场景中没有灰色 - 它是纯黑色和白色,“截图”图像的尺寸与我以编程方式生成的尺寸相同,但我似乎无法弄清楚灰色晕圈的来源。

UIView *printView = fullView;

UIGraphicsBeginImageContextWithOptions(printView.bounds.size, NO, 0.0);

CGContextRef ctx = UIGraphicsGetCurrentContext();
[printView.layer renderInContext:ctx];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
UIGraphicsEndImageContext();

我尝试在调用renderInContext之前添加以下内容以尝试阻止抗锯齿,但它没有明显的效果:

CGContextSetShouldAntialias(ctx, NO);
CGContextSetAllowsAntialiasing(ctx, NO);
CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh);

以下是两个不同输出的示例 - 左侧是我的代码生成的,右侧是正常的iOS屏幕截图:

enter image description here

由于我尝试将renderInContext的输出发送到单色打印机,因此打印机的抖动算法会导致灰色像素造成一些难看的瑕疵。

那么,我如何让renderInContext生成与真实设备截图相同的视图像素级输出 - 即只是原始场景中的黑白?

2 个答案:

答案 0 :(得分:3)

事实证明,该问题与UIImage使用的基础UIImageView的解析有关。 UIImage是使用数据提供程序创建的CGImageCGImage维度的指定单位与父UIImageView相同,但我使用的是带有视网膜显示屏的iOS设备。

由于CGImage维度是以非视网膜大小指定的,因此renderInContext升级了CGImage,显然这种升级行为与实际屏幕渲染所做的不同。 (出于某种原因,真实的屏幕渲染升级而不添加任何灰色像素。)

要解决这个问题,我创建的CGImage UIImageView尺寸是renderInContext的两倍,然后我对UIGraphicsBeginImageContextWithOptions()的调用会产生更好的黑白图像。在一些白色区域仍然有一些灰色像素,但它比原始问题有了很大的改进。

我终于通过将调用更改为UIImageView以强制它进行1.0的缩放来解决这个问题,并注意到UIGraphicsBeginImageContextWithOptions()黑色像素渲染不再有灰色光晕。当我强制{{1}}比例因子为2.0(由于视网膜显示而导致默认值)时,出现了灰色晕圈。

答案 1 :(得分:1)

我会尝试设置

 printView.layer.magnificationFilter

 printView.layer.minificationFilter

 kCAFilterNearest

图像是否显示在UIImageView个实例中? printView是他们的超级视图吗?