UIBezierPath描边1px线并填充1px宽度矩形 - 不同的结果。 [英] UIBezierPath stroke 1px line and fill 1px width rectangle - different results.

查看:160
本文介绍了UIBezierPath描边1px线并填充1px宽度矩形 - 不同的结果。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一张简单的图画

    

- (void)drawRect:(CGRect)rect
{
    //vertical line with 1 px stroking
    UIBezierPath *vertLine = [[UIBezierPath alloc] init];
    [vertLine moveToPoint:CGPointMake(20.0, 10.0)];
    [vertLine addLineToPoint:CGPointMake(20.0, 400.0)];
    vertLine.lineWidth = 1.0;
    [[UIColor blackColor] setStroke];
    [vertLine stroke];

    //vertical rectangle 1px width 
    UIBezierPath *vertRect= [UIBezierPath bezierPathWithRect:CGRectMake(40.0, 10.0, 1.0, 390.0)];
    [[UIColor blackColor] setFill];
    [vertRect fill];

}

在非视网膜3GS和模拟器上,第一行是模糊的看起来宽度超过1像素,但第二行很清晰。

On non retina 3GS and simulator the first line is blurry and looks wider than 1 px, but the second line is crisp.

不幸的是我没有测试iPhone4和新iPad,但在视网膜模拟器上两条线看起来都一样。

Unfortunately I have neither iPhone4 nor the new iPad to test, but on retina simulator both lines look the same.

问题:矩形而不是笔划是获得非视网膜和视网膜设备相同结果的唯一方法吗?

Question: Is rectangle instead of stroke the only way to obtain the same result for non retina and retina devices?

推荐答案

您正在填充矩形的内部,但是您正在从中心划线。由于两种情况下的坐标(矩形的角以及线中的起点和终点坐标)都被定义为整数值(无分数),因此坐标位于精确的点边界上。

You are filling the inside of the rectangle but you are stroking the line from the center. Since the coordinates in both cases (the corners of the rectangle and the start and end coordinates in the line) are defined as whole number values (no fractions), the coordinates lie on exact point boundaries.

在谈论线的点时,我说上面的坐标,不要将它们与屏幕上的点混淆。出于同样的原因,我也说点边界而不是像素边界。 iOS定义了它的坐标和所谓的点而不是像素的所有点。点是独立于分辨率的测量。视网膜和非视网膜设备在屏幕上具有相同数量的点,只是它们对应于不同数量的实际像素。

I said "coordinates" above when talking about the points of the line, to not confuse them with the points on the screen. I also said "point boundaries" instead of "pixel boundaries" for the same reason. iOS defines its coordinates and all the points in what is called "points" instead of pixels. A point is a resolution independent measurement. Both the retina and non-retina devices have the same number of points on the screen, it's just that they correspond to a different number of actual pixels.

让我们来看看抚摸与填充角点位于点边界的矩形相比,位于点边界上的线(如在您的问题中):

Let's look at stroking a line that lie on the point boundaries (like in your question) compared to filling a rectangle where the corners lie on the the point boundaries:

在下面的插图中,我是在非视网膜屏幕和视网膜屏幕上用黑色抚摸一条线并填充橙色矩形。我还用蓝色勾勒出线条和矩形。在这两种情况下,您都可以看到该分辨率的点大小,并将其与实际像素网格进行比较。

In the below illustrations I am stroking a line with black and filling a rectangle with orange on both a non-retina screen and a retina screen. I've also outlines the line and the rectangle with blue. In both cases you can see the size of a point for that resolution and compare it to the actual pixel grid.

在非视网膜情况下,您可以看到尝试使用1点线从中心划线(在这种情况下对应于1像素线宽)将填充顶部的一半像素和下面的像素的一半。由于像素仅填充了一半,因此这些像素的不透明度为50%。这导致较浅的颜色(在白色背景上)。由于顶部和底部的像素都是派对填充的,因此在顶部和底部都可以触摸填充像素。这使得线条看起来好像是2像素宽而不是1像素。

In the non-retina case, you can see that trying to stroke the line from the center with a 1 point line with (in this case corresponding to a 1 pixel line width) would fill half of the pixels on top and half on the pixels below. Since the pixels are only half filled, the opacity for those pixels are 50%. This results in the lighter color (on a white background). Since both the pixels on top and below are party filled, stroking the fills both the pixels on top and below. This makes the line look as if it's 2 pixels wide instead of one.

您可以快速将其与内部填充的矩形进行比较。

You can quickly compare that to the rectangle which is filled on the inside.

视网膜屏幕上的相同情况看起来不同。在这种情况下,一个点的大小是相同的,但它由4个像素而不是1组成。这次,当抚摸线时,线上半个点和线下半个点将完全填充像素行由于分辨率较高的屏幕,因此在上方和下方。这意味着该线看起来好像是1点宽并且颜色看起来完全不透明。

The same case on a retina screen looks different. In this case, the size of a point is the same but it consists of 4 pixels instead of 1. This time, when stroking the line, half a point above the line and half a point below the line will fully fill the row of pixels above and below because of the higher resolution screen. This means that the line looks as if it's 1 point wide and that the color looks fully opaque.

我们还可以看到填充的矩形看起来一样。

We can also see that the filled rectangle looks the same.

要解决此问题,您可以将线的点数设置为半像素。在低分辨率设备上从中心划线,意味着线向上延伸半个点,向下延伸半个点。由于线的中心现在位于点的中心,这意味着描边线完全位于像素内并且线看起来很清晰。这样做对视网膜线没有任何影响,因为向下(或向上)移动半个点,仍然意味着你完全填充上下像素。

To fix this, you would put the points for your line on half pixels. Stroking the line from the center on a low resolution device means that the line extends half a point upwards and half a point downwards. Since the center of the line now lies in the center of the point, this means that the stroked line fully lies within the pixels and the line looks sharp. Doing this won't have any effect on the retina line since moving down (or up) half a point, still means that you fully fill the pixels above and below.

在下图中(对于视网膜),我已经显示了点网格和像素网格。

In the illustration below (for retina) I have shown both the point grid and the pixel grid.


这篇关于UIBezierPath描边1px线并填充1px宽度矩形 - 不同的结果。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆