下面是一个简单的绘图
- (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个像素,但第二行是脆。
不幸的是我既没有iPhone4的也不是新的iPad进行测试,但视网膜模拟器两行看起来是一样的。
问:是长方形的,而不是行程以获得非视网膜和视网膜设备相同的结果的唯一途径?
您填写的矩形内,但你正在抚摸着从中心线上。 因为在这两种情况下的坐标(矩形的角部以及开始和在线端部坐标)被定义为整数值(无级分),则坐标位于上确切的点的边界。
我说谈论线的点的时候上面的“坐标”,不与屏幕上的点混淆。 我也说过,而不是“像素边界”出于同样的原因“点的边界”。 iOS的定义所谓的“点”,而不是像素的坐标和所有的点。 点是一个分辨率无关的测量。 无论是视网膜和非视网膜设备具有相同数量的屏幕上的点,这只是它们对应于不同数量的实际像素。
让我们来看看这抚摸趴在边界点(如在你的问题)相比,填充矩形,其中角趴在点边界线:
在下面的插图,我抚摸着用黑色的线,并分别通过非视网膜屏幕和视网膜屏幕上填充橙色矩形。 我也勾勒出线条,并用蓝色的矩形。 在这两种情况下,你可以看到该决议的一个点的大小,并将它与实际的像素网格。
在非视网膜的情况下,可以看到试图冲程从与具有1个点线的中心的线(在对应于1个像素线宽这种情况下)将填补一半像素的顶部和半上的像素下面。 由于像素只有半满,对于那些像素的不透明度为50%。 这将导致更轻的颜色(白色背景)。 由于两个顶部的像素和下方均方缭绕,轻抚同时填写在上面和下面的像素。 这使得线看起来好像是2个像素宽,而不是一个。
您可以快速地比较,为它填充在里面的矩形。
视网膜屏幕上的相同的情况下看起来不同。 在这种情况下,点的大小是相同的,但它由4个像素,而不是1。这时候,抚摸线时,线与线下方半个点以上半个点将完全填充像素的行上方和下方的更高分辨率的屏幕,因为。 这意味着该行看起来好像是1点宽和颜色看起来完全不透明。
我们也可以看到,填充矩形看起来是一样的。
为了解决这个问题,你可以把点上的半像素线。 抚摸从低分辨率设备上的中心的线表示该线延伸向上一半的点和半分向下。 由于线的中心目前位于该点的中心,这意味着描边线完全位于像素内和线条看起来锐利。 这样做会不会有,因为向下移动(或上)半点在视网膜上线的任何影响,仍然意味着你完全填充像素的上方和下方。
在下面的图例(对于视网膜)我已示出的点网格和象素网格两者。
你得到的笔触和填充不同的结果的原因是,他们的论点的解释是不同的。
在行程的坐标每一侧增加了线路的宽度的一半。 所以,你的观点是20.0和线路的宽度为1像素。 其结果将是(19.5-20.5)之间的1个像素的黑线,theorically。 由于没有在设备屏幕上的任何非整数像素,它将被转换(19-21)之间2个像素的灰度/模糊线上。 规避这一点,你需要总结每个坐标与0.5(如CGPointMake(20.5,10.5)),这样的宽度不会像素之间不再划分。
但是,在填充物中的参数被用于设定区域的边界进行填充,CGRectMake(40.0,10.0,1.0,390.0)意味着(40 - 41)之间的区域。 其结果是,没有小数部分落在像素看上去模糊不清。
文章来源: UIBezierPath stroke 1px line and fill 1px width rectangle - different results.