一、前言

事情的起因是这样的,因为需求的原因,有一个页面的cell分割线需要自定义,于是我的同事很顺其自然地用了个view,并将其高度设为1,来作为cell分割线使用。一切看起来都那么平静,直到有一天,产品大大的出现,打破了所有的宁静。他,一个带有血轮眼的男人,看出了高度为1的线与系统cell分割线的不同。如果他要是看了这篇文章的话,他就应该能明白我说的那句话的含义。3倍屏上高度为1的线与高度为1像素的线差别只是在2个像素的粗细,基本上已经超出了肉眼的识别能力。他,是一个传奇,一个可以与水哥抗衡的真汉子

~.png

好吧,言归正传,下面就来分析下高度为1的view线与系统cell分割线的区别在哪儿吧。在此之前先要搞懂下面这两坨东西。

二、Point与Pixel

2.1 Point与Pixel的概念

先来说下Pixel,翻译过来就是像素,屏幕上显示的最小单位。

Point,翻译过来就是点,是一个标准的长度单位。在编程中,frame、bounds、center等设置的坐标位置就是以point为单位。

2.2 Point与Pixel的关系

iPhone 4之前 non-retina 屏幕的设备,一个point 就代表一个像素,在此就不做过多说明。之后的retina屏幕(视网膜屏),两者之间的关系见下表:

设备

尺寸

scale

iPhone4s

320,480

2

iPhone5/5s

320,568

2

iPhone6

375,667

2

iPhone6s

414,736

2

iPhone6plus

414,736

3

...

...

3

scale根据代码可以获取:

CGFloat scale = [UIScreen mainScreen].scale

基于以上信息可以看出,我们大部分情况下都不需要去关注pixel,然而存在部分情况需要考虑像素的转化。比如说绘制一个1像素粗细的线。

看到这个问题,第一想法就是根据当前屏幕的缩放因子scale计算出1像素线对应的点,然后将其设置成线的粗细即可。

没错,我当时就这么干了。代码写完,编译运行发现在设备上有的线并没有显示出来。

我在万能的互联网上找到了原因:

为了获得良好的视觉效果,绘图系统通常都会采用一个叫antialiasing(反锯齿)的技术,iOS也不例外。显示屏幕有很多个显示单元(即像素)组成,如果要画一条黑线,这条线刚好落在了一列或者一行显示单位之内,将会渲染出标准的一个像素的黑线。如下图所示:

渲染出标准黑线.jpg

但是如果线落在乐两个行或列的中间时,那么会得到一条失真的线,如下图所示:

1Point的线卡在两个像素之间.jpg

官方给出的解释与解决办法是这样的

解释:

Positions defined by whole-numbered points fall at the midpoint between pixels. For example, if you draw a one-pixel-wide vertical line from (1.0, 1.0) to (1.0, 10.0), you get a fuzzy grey line. If you draw a two-pixel-wide line, you get a solid black line because it fully covers two pixels (one on either side of the specified point). As a rule, lines that are an odd number of physical pixels wide appear softer than lines with widths measured in even numbers of physical pixels unless you adjust their position to make them cover pixels fully.

奇数像素宽度的线在渲染的时候将会表现为柔和的宽度扩展到向上的整数宽度的线,除非你手动的调整线的位置,使线刚好落在一行或列的显示单元内。

解决办法

On a low-resolution display (with a scale factor of 1.0), a one-point-wide line is one pixel wide. To avoid antialiasing when you draw a one-point-wide horizontal or vertical line, if the line is an odd number of pixels in width, you must offset the position by 0.5 points to either side of a whole-numbered position. If the line is an even number of points in width, to avoid a fuzzy line, you must not do so.

On a high-resolution display (with a scale factor of 2.0), a line that is one point wide is not antialiased at all because it occupies two full pixels (from -0.5 to +0.5). To draw a line that covers only a single physical pixel, you would need to make it 0.5 points in thickness and offset its position by 0.25 points. A comparison between the two types of screens is shown in Figure 1-4.

1.在non-retina屏上,一个Point对应一个像素。为了防止antialiasing导致的奇数像素的线渲染时出现失真,你需要设置偏移0.5个点。

2.在retina屏上,要绘制一个像素的线,需要设置线宽为0.5个点,同时设置偏移为0.25个点。

3.如果线宽为偶数Point的话,则不要去设置偏移,否则线条也会失真。

至此似懂非懂地貌似察觉到了解决办法,但是上面给出的解决方法需要偏移的点数也只是在二倍屏的基础上。如果为三倍屏,又该偏移多少呢?

下面就来分析下偏移量的计算。

首先设置为1Pixel的线,其所用的点为1 / [UIScreen mainScreen].scale。渲染的时候,如果我们检测到线的落点并没有完美显示在显示单元上(奇数单元点),只需要将其移动半个单元到偶数单元点,即可使线渲染的时候躲过** antialiasing**这个门槛。

即1像素的线需要的偏移量为1 / [UIScreen mainScreen].scale/2

三、核心代码

下面贴上绘制1像素线的核心代码:

- (void)drawRect:(CGRect)rect

{

[super drawRect:rect];

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextBeginPath(context);

CGFloat pixelAdjustOffset = 0;

// 落在奇数位置的显示单元上

if (((int)(1* [UIScreen mainScreen].scale) + 1) % 2 == 0)

{

pixelAdjustOffset = SINGLE_LINE_ADJUST_OFFSET;

}

// 设置画线y值

CGFloat yPos = 1 - pixelAdjustOffset;

// 如果想在view的最底部画线,需设置lineMode为EUCPixelViewLineModeBottom

if (self.lineMode == EUCPixelViewLineModeBottom)

{

while (yPos + 1 < self.bounds.size.height) {

yPos ++;

}

}

CGContextMoveToPoint(context, 0, yPos);

CGContextAddLineToPoint(context, self.bounds.size.width, yPos);

CGContextSetLineWidth(context, 1);

CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);

CGContextStrokePath(context);

}

有时间补上github上的demo地址

谢谢观看!

手机1像素线粗_iOS绘制1像素线的正确姿势相关推荐

  1. 手机1像素线粗_A4纸1像素的线打印出来多少毫米粗,能轻松看出来吗?

    呵呵,这个问题要看你电脑的分辨率是多大而决定的: 300像素/英寸,a4大小是2479x3508 120像素/英寸,a4大小是1487x2105 a4是2480*3508象素 210*297毫米 分辨 ...

  2. 手机1像素线粗,如何模仿1像素厚的线?

    like it has 1 pixel with but there are empty spaces above and below line. It can be seen if place tw ...

  3. html5绘制股票图形,股票数据分析(五):绘制股票k线图(js+canvas + Python + json)

    本文介绍:利用 js+canvas 绘制股票k线图 HTML5 标签用于绘制图像(通过脚本,通常是 JavaScript). 不过, 元素本身并没有绘制能力(它仅仅是图形的容器) - 您必须使用脚本来 ...

  4. 手机1像素线粗_关于移动端开发 1px 线的一些理解和解决办法

    (给前端大全加星标,提升前端技能) 作者: 大转转FE/李兴瑞 1px线变粗的原因 在做移动端项目时,常常是根据设计图设置元素节点的大小和样式,但是有时候根据设计图写出来的样式还是不如人意,虽然表面上 ...

  5. HTML1个像素宽的代码,HTML5 Canvas中绘制一个像素宽的细线实现代码详情

    正统的HTML5 Canvas中如下代码ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(10, 100); ctx.lineTo(300,100); ct ...

  6. 使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头~)

    使用Python,OpenCV进行涂鸦(绘制文字.线.圆.矩形.椭圆.多边形轮廓.多边形填充.箭头) 1. 效果图 2. 原理 2.1 绘制线:cv2.line(canvas, (300, 0), ( ...

  7. iphonex如何关机_iPhone X手机屏幕出现绿线怎么回事_屏幕绿线该如何处理?

    近期朋友买来iphone x,用了一段时间发现屏幕上有一条绿线,极度影响美观与操作体验.那么应该怎么解决这个问题呢?下面西安苹果维修点为大家解答关于iPhoneX屏幕绿线的故障问题. iphoneX手 ...

  8. 【OpenGL】十二、OpenGL 绘制线段 ( 绘制单条线段 | 绘制多条线段 | 依次连接的点组成的线 | 绘制圈 | 绘制彩色的线 )

    文章目录 一.设置线宽度 二.绘制单条线段 GL_LINES 三.绘制多条线段 GL_LINES 四.绘制依次连接的点组成的线 GL_LINE_STRIP 五.绘制圈 GL_LINE_LOOP ( 偶 ...

  9. WPF 绘制对齐像素的清晰显示的线条

    WPF 绘制对齐像素的清晰显示的线条 原文:WPF 绘制对齐像素的清晰显示的线条 版权声明:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可.欢迎转载.使用.重新发布, ...

最新文章

  1. 两个小技巧,马上加快上网速度
  2. dwr消息推送和tomcat集群
  3. 小学计算机国培研修总结,小学数学国培研修总结
  4. 频段表_VoLTE高低频段覆盖能力研究
  5. FFmpeg基础库编程开发学习笔记——视频常见格式
  6. 【粉丝福利】Logo评选投票,礼品赠送!
  7. Bash 远程任意代码执行安全漏洞
  8. 删除远程桌面登录的记录(mstsc)
  9. OMRON软件安装与配置
  10. mysql外键级联操作_Mysql 外键级联
  11. 【干货】如何写微信公众号文章:文章流畅耐读的奥秘
  12. android 9 qq登录,【报Bug】安卓离线打包targetSdkVersion设置28时,在安卓9.0手机上QQ授权登录闪退...
  13. 微信公众号文章转语音tts
  14. Hyperic-Sigar简介
  15. 护眼灯真的可以保护眼睛吗?2022双十二选哪款护眼灯对孩子眼睛好
  16. 使用STLINK下载程序到STM8S103问题汇总
  17. GDUT 2.25 A
  18. 华为od德科面试数据算法解析 2022-8-8 欢乐的周末
  19. 2021智慧物流领域最具商业合作价值企业盘点
  20. 用计算机用u盘怎么切换,U盘一插进电脑提示需要格式化怎么办?

热门文章

  1. 纯java视频转图片,对图片换脸,再次图片合成视频,java视频换脸
  2. python3如何构建文本向量
  3. 20221228今天的世界发生了什么
  4. 【一日一logo_day_23】五角星
  5. word设置奇偶页面
  6. Android单目手势识别,手势交互点亮智博会 微动手势识别技术瞩目C位
  7. tar 解压缩命令详细参数
  8. 灵活的体现输入框的提示语句
  9. VUE项目运行常用命令
  10. python函数的声明_Python函数声明与定义