【问题标题】:CoreGraphics line appears to change size?CoreGraphics 线似乎改变了大小?
【发布时间】:2012-02-21 18:01:29
【问题描述】:

我的形状周围有这条线:

问题是,它显然从 1px 厚到 2px。这是我正在使用的代码:

CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, rect);

    CGContextSetFillColorWithColor(context, [BUTTON_COLOR CGColor]);
    CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
    CGContextSetLineWidth(context, 1);

    int radius = 8;


    CGContextMoveToPoint(context, 0, self.frame.size.height / 2);

    CGContextAddLineToPoint(context, POINT_WIDTH, self.frame.size.height);

    CGContextAddLineToPoint(context, rect.origin.x + rect.size.width - radius, 
                            rect.origin.y + rect.size.height);

    CGContextAddArc(context, rect.origin.x + rect.size.width - radius, 
                    rect.origin.y + rect.size.height - radius, radius, M_PI / 2, 0.0f, 1);

    CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + radius);

    CGContextAddArc(context, rect.origin.x + rect.size.width - radius, rect.origin.y + radius, 
                    radius, 0.0f, -M_PI / 2, 1);

    CGContextAddLineToPoint(context, POINT_WIDTH, 0);

    CGContextAddLineToPoint(context, 0, self.frame.size.height / 2);

    CGContextClosePath(context);
    CGContextDrawPath(context, kCGPathFillStroke);

有什么想法吗?

【问题讨论】:

    标签: iphone objective-c core-graphics


    【解决方案1】:

    您的顶部、底部和右侧边缘看起来比对角线更细的原因是因为您将沿这些边缘绘制的线剪掉了一半。正如 Costique 所提到的,Core Graphics 会绘制一个笔触,使其在路径上居中。这意味着一半的笔划位于路径的一侧,一半的笔划位于另一侧。由于您的路径正好沿着视图的顶部、右侧和底部边缘延伸,因此一半的笔划落在视图的边界之外并且不会被绘制。

    Costique 也是正确的,您应该将路径移动 0.5 点。 (从技术上讲,您应该移动笔划宽度的一半。)但是,您没有根据 rect 变量统一指定坐标,因此很难移动所有路径。

    您要做的是在两个维度上将rect 插入0.5,调整您的图形上下文,使其原点位于rect.origin,并仅使用rect.size 来获取您的坐标,而不是self.frame.size。这是我的测试:

    - (void)drawRect:(CGRect)dirtyRect
    {
        CGContextRef gc = UIGraphicsGetCurrentContext();
        CGContextSaveGState(gc); {
    
            CGContextSetFillColorWithColor(gc, [UIColor colorWithWhite:.9 alpha:1].CGColor);
            CGContextSetStrokeColorWithColor(gc, [[UIColor blackColor] CGColor]);
            CGContextSetLineWidth(gc, 1);
    
            static const CGFloat Radius = 8;
            static const CGFloat PointWidth = 20;
    
            CGRect rect = CGRectInset(self.bounds, .5, .5);
            CGContextTranslateCTM(gc, rect.origin.x, rect.origin.x);
            rect.origin = CGPointZero;
    
            CGContextMoveToPoint(gc, 0, rect.size.height / 2);
    
            CGContextAddLineToPoint(gc, PointWidth, rect.size.height);
    
            CGContextAddLineToPoint(gc, rect.origin.x + rect.size.width - Radius, 
                                    rect.origin.y + rect.size.height);
    
            CGContextAddArc(gc, rect.origin.x + rect.size.width - Radius, 
                            rect.origin.y + rect.size.height - Radius, Radius, M_PI / 2, 0.0f, 1);
    
            CGContextAddLineToPoint(gc, rect.origin.x + rect.size.width, rect.origin.y + Radius);
    
            CGContextAddArc(gc, rect.origin.x + rect.size.width - Radius, rect.origin.y + Radius, 
                            Radius, 0.0f, -M_PI / 2, 1);
    
            CGContextAddLineToPoint(gc, PointWidth, 0);
    
            CGContextAddLineToPoint(gc, 0, rect.size.height / 2);
    
            CGContextClosePath(gc);
            CGContextDrawPath(gc, kCGPathFillStroke);
    
        } CGContextRestoreGState(gc);
    }
    

    结果如下:

    【讨论】:

    • 另请参阅this answer 以获取问题的特写图。
    【解决方案2】:

    Core Graphics 在路径边缘绘制笔画,即笔画宽度的一半位于路径内部,另一半位于路径外部。由于您不能在视图之外绘制,因此一半的笔划会被上下文剪裁。您必须将路径插入笔划宽度的一半。

    完整的例子:

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, rect);
    
    CGContextSetFillColorWithColor(context, [BUTTON_COLOR CGColor]);
    CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
    CGContextSetLineWidth(context, 1);
    
    int radius = CORNER_RADIUS;
    
    CGRect pathRect = CGRectInset(self.bounds, 0.5f, 0.5f);
    
    CGContextMoveToPoint(context, CGRectGetMinX(pathRect), CGRectGetMidY(pathRect));
    CGContextAddLineToPoint(context, CGRectGetMinX(pathRect) + POINT_WIDTH, CGRectGetMaxY(pathRect));
    CGContextAddArc(context, CGRectGetMaxX(pathRect) - radius, 
                    CGRectGetMaxY(pathRect) - radius, radius, M_PI / 2, 0.0f, 1);
    CGContextAddArc(context, CGRectGetMaxX(pathRect) - radius, CGRectGetMinY(pathRect) + radius, 
                    radius, 0.0f, -M_PI / 2, 1);
    CGContextAddLineToPoint(context, CGRectGetMinX(pathRect) + POINT_WIDTH, CGRectGetMinY(pathRect));
    
    CGContextClosePath(context);
    CGContextDrawPath(context, kCGPathFillStroke);
    

    请注意,删除了几个多余的绘图命令而不影响结果。享受吧。

    【讨论】:

    • 最好手动将所有路径点移动 0.5 pt“内部”。只需调整点的坐标即可。
    • 左边的线条仍然比其他线条粗。它们似乎太厚了 0.5。任何想法如何摆脱它?
    • @Andrew 这绝对是抗锯齿,它使所有曲线和斜线看起来比水平线和垂直线更粗。老实说,我不知道如何处理那个,除了使笔划明显变宽。
    猜你喜欢
    • 1970-01-01
    • 2021-12-11
    • 2012-10-10
    • 2021-10-09
    • 2017-11-20
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多