9

我需要在没有抗锯齿的情况下渲染 UIBezierPaths,然后将它们保存为 PNG 以保留完整的像素表示(例如,不要让 JPEG 弄脏图像)。在抚摸 UIBezierPaths 之前,我尝试过调用下面的 CG 函数,但似乎对生成的渲染图像没有任何影响。路径仍然使用抗锯齿(即平滑)渲染。

CGContextSetShouldAntialias(c, NO);
CGContextSetAllowsAntialiasing(c, NO);
CGContextSetInterpolationQuality(c, kCGInterpolationNone);

任何点击将不胜感激。

4

2 回答 2

16

当我使用这些选项时,它会关闭抗锯齿。左边是默认选项。在右边,有你的选择。

在此处输入图像描述

如果您使用UIView子类,这很容易控制。这是我的drawRect

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetShouldAntialias(context, NO);

    [[UIColor redColor] setStroke];
    UIBezierPath *path = [self myPath];
    [path stroke];
}

并捕获屏幕,从如何以编程方式截取屏幕截图

- (void)captureScreen
{
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
        UIGraphicsBeginImageContextWithOptions(self.window.bounds.size, NO, [UIScreen mainScreen].scale);
    else
        UIGraphicsBeginImageContext(self.window.bounds.size);
    [self.window.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    NSData *data = UIImagePNGRepresentation(image);
    [data writeToFile:[self screenShotFilename] atomically:YES];
}

如果您使用的是CAShapeLayer,那么我认为您无法控制屏幕上的抗锯齿,因为正如文档所述

该形状将被抗锯齿绘制,并尽可能在光栅化之前将其映射到屏幕空间以保持分辨率独立性。但是,应用于图层或其祖先的某些类型的图像处理操作(例如 CoreImage 过滤器)可能会强制在局部坐标空间中进行光栅化。

但是,不管屏幕上的抗锯齿如何,如果你想让你的屏幕快照不被抗锯齿,你可以将你的插入CGContextSetShouldAntialiascaptureScreen例程中:

- (void)captureScreen
{
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
        UIGraphicsBeginImageContextWithOptions(self.window.bounds.size, NO, [UIScreen mainScreen].scale);
    else
        UIGraphicsBeginImageContext(self.window.bounds.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetShouldAntialias(context, NO);
    [self.window.layer renderInContext:context];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    NSData * data = UIImagePNGRepresentation(image);
    [data writeToFile:[self screenShotFilename] atomically:YES];
}
于 2013-03-14T19:16:02.580 回答
5

你从哪里来c?您确定这与您使用的绘图周期中c的内容相同吗?从上面的样本很难看出。UIGraphicsGetCurrentContext()[UIBezierPath stroke]

如果您想确定您正在绘制到您正在配置的相同上下文,请CGPath从 中获取UIBezierPath,然后直接绘制它:

- (void)drawRect:(CGRect)rect {
  CGContextRef context = UIGraphicGetCurrentContext();
  CGPathRef path = [self.bezier CGPath];
  CGContextSetShouldAntialias(context, NO);
  CGContextAddPath(context, path);
  CGContextStrokePath(context);
}
于 2013-03-14T19:14:19.383 回答