禁用UIBezierPath的抗锯齿功能

问题描述 投票:6回答:2

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

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

任何点击都将非常感激。

ios core-graphics
2个回答
13
投票

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

enter image description here

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

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

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

并从How to take a screenshot programmatically捕获屏幕

- (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,那么我认为你不能在屏幕上控制抗锯齿,因为as the documentation says

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

但是,无论屏幕上的抗锯齿如何,如果您想让屏幕快照不被抗锯齿,您可以将CGContextSetShouldAntialias插入captureScreen例程:

- (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];
}

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);
}
© www.soinside.com 2019 - 2024. All rights reserved.