CGContextSetLineWidth (context, 1) - ширина почти всегда равна минимум 2 пикселям вместо 1 - PullRequest
13 голосов
/ 09 января 2010

При 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);
}

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

Я рисую в CALayer, и у меня есть изображение с изображением под слоем, как я уже тестировал - если я рисую на чистом белом виде - линию можно нарисовать с шириной 1, но не на изображении

Ответы [ 3 ]

28 голосов
/ 09 января 2010

Ширина линии действительно составляет 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);
23 голосов
/ 22 октября 2010

точка пикселя расположена между 2 пикселями, как сказал KennyTM, и линия по умолчанию имеет Antialiased перед отображением на экране, поэтому она отображается как width = 2.0, отключение Antialias может решить проблему либо.

CGContextSetShouldAntialias(context, NO);

от: sfkaos на iphonedevsdk

Я пытался, у меня отлично работает.

0 голосов
/ 24 сентября 2014

Я согласен с KennyTM, однако мне пришлось добавить 0,5 к оси Y, а не к оси X, чтобы моя линия показывала половину. Я предполагаю, что это зависит от того, каким образом проходит ваша линия, то есть по горизонтали или по вертикали!

...