CGContextSetLineWidth(context, 1) - 宽度几乎总是至少 2 像素而不是 1

发布于 2024-08-17 06:33:27 字数 2503 浏览 6 评论 0原文

使用 CGContextSetLineWidth(context, 1) ,宽度几乎总是至少 2 个像素,而不是 1

QQCandleStickLayer.m

-(id)init
{
    self = [super init];
    if(self != nil)
    {       
        self.delegate = self;       
        self.opaque = NO;       
    }
    return self;
}

- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context{

    CGContextSetLineWidth(context, 1.0f);
    CGContextSetAllowsAntialiasing(context, false);
    CGContextSetShouldAntialias(context, false);
    CGContextSetInterpolationQuality(context,kCGInterpolationNone);
    CGContextSetShadowWithColor(context, CGSizeMake( 0.0, 0.0 ), 0, NULL);


    CGContextMoveToPoint(context, self.bounds.origin.x+30.5f, self.bounds.origin.y+self.bounds.size.height-indent);
    CGContextAddLineToPoint(context, self.bounds.origin.x+30.5f, self.bounds.origin.y+self.bounds.size.height-(self.bounds.size.height-lastY)); 
    CGContextClosePath(context);
    CGContextSetRGBStrokeColor(context, 119.0f/255, 119.0f/255, 119.0f/255, 1.0);
    CGContextStrokePath(context);
}

QQDeflviumLayer.m

- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context{  
    UIImage *myDefluvium = [UIImage imageNamed:@"delfluviumNewRotatedSmall.png"];
    CGLayerRef layerCircle = CGLayerCreateWithContext(context, myDefluvium.size,NULL);
    if (layerCircle)
    {
        CGContextRef layerContext = CGLayerGetContext(layerCircle);
        CGContextDrawImage(layerContext, (CGRect){ CGPointZero, myDefluvium.size }, myDefluvium.CGImage);       
        CGContextDrawLayerInRect(context, CGRectMake(layer.bounds.origin.x,layer.bounds.origin.y, layer.bounds.size.width,layer.bounds.size.height), layerCircle);
        CFRelease(layerCircle);
    }
}

QuickQuoteViewController.m

defluviumLayer=[[QQDefluviumLayer alloc] init];
    [defluviumLayer setBounds:CGRectMake(0, 0, 61, 343)];
    [defluviumLayer setPosition:CGPointMake(277,246)];
    [self.view.layer addSublayer:defluviumLayer];
    [defluviumLayer update];


    candleStickLayer=[[QQCandleStickLayer alloc] init];
    [candleStickLayer setBounds:CGRectMake(0,0, defluviumLayer.frame.size.width, defluviumLayer.frame.size.height)];
    [candleStickLayer setPosition:CGPointMake(defluviumLayer.position.x,defluviumLayer.position.y)];
    [self.view.layer addSublayer:candleStickLayer];
    [candleStickLayer update];

我正在 CALayer 中绘制,并且图像位于图层下方,正如我测试过的 - 如果我在清晰的白色视图上绘制 - 可以用宽度 1 绘制线条,但不能在图像上绘制

With CGContextSetLineWidth(context, 1) the width is almost alwayas at least 2 pixels instead 1

QQCandleStickLayer.m

-(id)init
{
    self = [super init];
    if(self != nil)
    {       
        self.delegate = self;       
        self.opaque = NO;       
    }
    return self;
}

- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context{

    CGContextSetLineWidth(context, 1.0f);
    CGContextSetAllowsAntialiasing(context, false);
    CGContextSetShouldAntialias(context, false);
    CGContextSetInterpolationQuality(context,kCGInterpolationNone);
    CGContextSetShadowWithColor(context, CGSizeMake( 0.0, 0.0 ), 0, NULL);


    CGContextMoveToPoint(context, self.bounds.origin.x+30.5f, self.bounds.origin.y+self.bounds.size.height-indent);
    CGContextAddLineToPoint(context, self.bounds.origin.x+30.5f, self.bounds.origin.y+self.bounds.size.height-(self.bounds.size.height-lastY)); 
    CGContextClosePath(context);
    CGContextSetRGBStrokeColor(context, 119.0f/255, 119.0f/255, 119.0f/255, 1.0);
    CGContextStrokePath(context);
}

QQDefluviumLayer.m

- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context{  
    UIImage *myDefluvium = [UIImage imageNamed:@"delfluviumNewRotatedSmall.png"];
    CGLayerRef layerCircle = CGLayerCreateWithContext(context, myDefluvium.size,NULL);
    if (layerCircle)
    {
        CGContextRef layerContext = CGLayerGetContext(layerCircle);
        CGContextDrawImage(layerContext, (CGRect){ CGPointZero, myDefluvium.size }, myDefluvium.CGImage);       
        CGContextDrawLayerInRect(context, CGRectMake(layer.bounds.origin.x,layer.bounds.origin.y, layer.bounds.size.width,layer.bounds.size.height), layerCircle);
        CFRelease(layerCircle);
    }
}

QuickQuoteViewController.m

defluviumLayer=[[QQDefluviumLayer alloc] init];
    [defluviumLayer setBounds:CGRectMake(0, 0, 61, 343)];
    [defluviumLayer setPosition:CGPointMake(277,246)];
    [self.view.layer addSublayer:defluviumLayer];
    [defluviumLayer update];


    candleStickLayer=[[QQCandleStickLayer alloc] init];
    [candleStickLayer setBounds:CGRectMake(0,0, defluviumLayer.frame.size.width, defluviumLayer.frame.size.height)];
    [candleStickLayer setPosition:CGPointMake(defluviumLayer.position.x,defluviumLayer.position.y)];
    [self.view.layer addSublayer:candleStickLayer];
    [candleStickLayer update];

I'm drawing in a CALayer, and have Image with image below layer, as I have tested - if i draw on clear white view - the line can be drawn with width 1, but not on the image

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

太阳男子 2024-08-24 06:33:27

线宽确实是 1 像素宽,但一侧为 0.5 像素宽,另一侧为 0.5 像素宽。将其粘贴到像素网格上,使其两侧看起来都是 1 像素宽、不透明度为 50%,从而使其成为一条 2 像素宽、不透明度为 50% 的线。

为了避免这种情况,请在半像素坐标上绘制线条。

例如,而不是

CGContextMoveToPoint(ctx, 20.0f, 30.0f);
CGContextAddLineToPoint(ctx, 20.0f, 100.0f);

CGContextMoveToPoint(ctx, 20.5f, 30.0f);
CGContextAddLineToPoint(ctx, 20.5f, 100.0f);

The line width is indeed 1 pixel wide, but 0.5 pixel wide on one side and 0.5 pixel wide on the other side. Sticking it to the pixel grids makes appears to be 1 pixel wide at 50% opacity on both sides, making it a 2 pixel wide line at 50% opacity.

To avoid this, draw the line on half-pixel coordinates.

For example, instead of

CGContextMoveToPoint(ctx, 20.0f, 30.0f);
CGContextAddLineToPoint(ctx, 20.0f, 100.0f);

do

CGContextMoveToPoint(ctx, 20.5f, 30.0f);
CGContextAddLineToPoint(ctx, 20.5f, 100.0f);
记忆で 2024-08-24 06:33:27

正如KennyTM所说,像素点位于2个像素之间,并且在显示之前默认对线条进行抗锯齿处理,因此显示宽度= 2.0,关闭抗锯齿也可以解决问题。

CGContextSetShouldAntialias(context, NO);

来自: iphonedevsdk 上的 sfkaos

我尝试过,有效对我来说很好。

the point of pixel is located between 2 pixels like KennyTM said, and the line by default is Antialiased before go display, so it appears as width = 2.0, turn off Antialias can fix the problem either.

CGContextSetShouldAntialias(context, NO);

from: sfkaos on iphonedevsdk

I tried, works fine for me.

极致的悲 2024-08-24 06:33:27

我同意 KennyTM 的观点,但是我必须在 Y 轴而不是 X 轴上添加 0.5 才能让我的线条显示一半。我想这取决于你的线走向,即水平或垂直!

I agree with KennyTM, however I had to add the 0.5 to the Y axis, not the X axis to get my line to show half. I guess it depends which way your line goes, i.e. horizontal or vertical!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文