IOSCGContextSetLineWidth无法设置1像素线宽?-创新互联

前段时间美术在验收界面时提了问题:为啥要求1像素宽的一个矩形框似乎却变成了2,3个像素宽。仔细检查过代码后发现,的确设置了LineWidth为1,但绘制效果却并不如人愿。似乎在ios上绘制最低要2个像素的线宽。

10年积累的成都网站设计、成都网站制作、外贸网站建设经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先网站设计后付款的网站建设流程,更有昭通免费网站建设让你可以放心的选择与我们合作。创新互联建站专注于洛浦网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供洛浦营销型网站建设,洛浦网站制作、洛浦网页设计、洛浦网站官网定制、小程序开发服务,打造洛浦网络公司原创品牌,更为您提供洛浦网站排名全网营销落地服务。创新互联专注于金凤网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供金凤营销型网站建设,金凤网站制作、金凤网页设计、金凤网站官网定制、微信小程序定制开发服务,打造金凤网络公司原创品牌,更为您提供金凤网站排名全网营销落地服务。

查看文档后发现造成这个问题的原因是Quartz的抗锯齿机制。一种粗暴的解决方案是不采用抗锯齿,即:CGContextSetShouldAntialias(context, NO)。但是显而易见的问题是取消抗锯齿会导致绘制效果变差。而另外一种方案则比较取巧:将绘制调整到半像素坐标系上:

比如 CGContextMoveToPoint(context, 100.0, 100.0); CGContextAddLineToPoint(context, 100.0, 200.0);改为 CGContextMoveToPoint(context, 100.5, 100.5); CGContextAddLineToPoint(context,100.5, 200.5);

这是因为:所谓的线宽指的是给定路径的中心到两边的粗细,换句话是在路径的两边各绘制一半。如图

IOS CGContextSetLineWidth无法设置1像素线宽?

在绘制线宽为1的直线(3,1)到(3,5)时,实际上是占据了左右两个像素各半个像素,而真正绘制时当然是以一个像素为标准单位,所以浅蓝色区域就会以相近的方式进行渲染。这也是宽为1.0的线绘制并不准确的原因。而当将绘制中心调整到半个像素上就不会有这个问题,见右图:(3.5,1)到(3.5,5)。详细可以参考mozilla canvas绘制的文档。

最后上一个在ios上绘制带圆角矩形的代码:

if (radius <= 0) { CGContextAddRect(context, rect); return; } CGContextSaveGState(context); CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect)); CGContextScaleCTM(context, radius, radius); NSInteger width = CGRectGetWidth(rect) / radius; NSInteger height = CGRectGetHeight(rect) / radius; NSInteger halfWidth = width / 2; NSInteger halfHeight= height / 2; CGContextMoveToPoint (context, width + 0.5, halfHeight + 0.5); CGContextAddArcToPoint(context, width + 0.5, height + 0.5, halfWidth + 0.5, height + 0.5, 1); CGContextAddArcToPoint(context, 0 + 0.5, height + 0.5, 0 + 0.5, halfHeight + 0.5, 1); CGContextAddArcToPoint(context, 0 + 0.5, 0 + 0.5, halfWidth + 0.5, 0 + 0.5, 1); CGContextAddArcToPoint(context, width + 0.5, 0 + 0.5, width + 0.5, halfHeight + 0.5, 1); CGContextClosePath(context); CGContextRestoreGState(context);

原文转载:http://xiangwangfeng.com/2012/03/24/为啥cgcontextsetlinewidth设置不了1pixel线框?/

以下是自己测试得出的结论,如有异意请各位老师不吝赐教,谢谢!

由于retina屏幕是640像素,而非retina是320,所以,分两种情况,在retina屏幕下和非retina屏幕下。

画一条从点(10.0, 10.0)到点(10.0, 100.0)的直线和点(10.5, 10.5)到点(10.5, 100.5)的直线,产生的样式,上面都解释了。

我想说的是从点(10.3, 10.3)到点(10.3, 100.3)的黑色一个像素的直线,CGContextSetShouldAntialias(context, YES)。

一、在retina屏幕下

==IOS CGContextSetLineWidth无法设置1像素线宽?==这个图片是我画出的线放大后的效果,我计算了,它绘制的是20、21、22这三个像素值,也就是说10.3 * 2 = 20.6;那么它会将第21个像素值绘制黑色,两边的绘制暗色。

二、在非retina屏幕下

==IOS CGContextSetLineWidth无法设置1像素线宽?==这个图片是我画出的线放大后的效果,计算后,它绘制的是10、11这两个像素值,那么它会将第11个像素值绘制黑色,10的绘制成暗色。

我还要说从点(10.7, 10.7)到点(10.7, 100.7)的黑色一个像素的直线,CGContextSetShouldAntialias(context, YES)。

一、在retina屏幕下

图片样式还是一样的,但是位置变了,这次画的是21、22、23这三个像素值,也就是说10.7 * 2 = 21.4;那么他是将第22个像素值绘制黑色,两边的绘制暗色。

二、在非retina屏幕下

==IOS CGContextSetLineWidth无法设置1像素线宽?==这个图片是我画出的线放大后的效果,计算后,它绘制的是11、12这两个像素值,那么它会将第11个像素值绘制黑色,12的绘制成暗色。

在说一说CGContextSetShouldAntialias(context, NO)。10.3和10.7的结果如下

一、在retina屏幕下

绘制位置都一样,但是样式变了,变成没有暗色全是黑色。

二、在非retina屏幕下

位置样式都变了,颜色只是黑色,并且都只画了第11个像素

总结-----

其实就一句话,“所谓的线宽指的是给定路径的中心到两边的粗细,换句话是在路径的两边各绘制一半”。这个原理明白了,啥都没问题了。

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。

本文标题:IOSCGContextSetLineWidth无法设置1像素线宽?-创新互联
分享路径:https://www.cdcxhl.com/article12/cehsgc.html

成都网站建设公司_创新互联,为您提供虚拟主机移动网站建设电子商务响应式网站网页设计公司营销型网站建设

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

成都做网站