移动端高清多屏适配的解决方案

1 平常开发,移动端场景:

  • 开发移动端H5页面
  • 面对不同分辨率的手机
  • 面对不同屏幕尺寸的手机

2 视觉稿:对于移动端的开发而言,为了做到页面高清的效果,经常会对视觉稿有如下规范

  • 首先选取一款手机屏幕作为基准(更多的是iphone6的375*667)
  • 对于retina屏幕(比如dpr=2),为了达到高清的效果,视觉稿的大小会是基准的两倍,也就是说像素点的个数是原来的四倍(对于iphone6来说,375667 变成了 7501334)

3 引出两个问题

  • 对于dpr = 2 的手机,胃泌素画布大小 x2 就可以解决高清问题?
  • dpr=物理像素/设备独立像素(可能就是分辨率吧)
  • 对于2倍大小的视觉稿,在具体的css编码中如何还原每一个区块 的真实宽高?
  • 当dpr=1 时候,通过1个设备独立像素显示一个css像素,当dpr=2的时候,通过4个设备独立像素(=2个物理像素)显示1个css像素(所以如果图片的css像素不足会出现模糊的情况),当dpr=3的时候,通过9个设备独立像素(=3个物理像素)显示一个css像素.

4 由问题来看下基本的定义以及概念

  • 物理像素(设备像素) : (physical pixel)一个物理像素是显示器(手机屏幕)上最小的物理显示单元,在操作系统的调度下,每一个设备独立像素都有自己的颜色值和亮度值

  • 设备独立像素 : (dp/dip density-independent pixel) 可以认为是计算机坐标系统中得一个点,这个点代表一个可以由程序使用并控制的虚拟像素(比如:CSS 像素,只是在android机中CSS 像素就不叫”CSS 像素”了而是叫”设备独立像素”),然后由相关系统转换为物理像素。(跟设备的宽高一致),也成为逻辑像素

  • CSS像素:CSS像素是Web编程的概念,独立于设备的用于逻辑上衡量像素的单位,也就是说我们在做网页时用到的CSS像素单位,是抽象的,而不是实际存在的。单位是px(是一个像素单位,相对的是设备独立像素)

  • css像素==设备独立像素==逻辑像素

  • 位图像素(png,jpg)是由像素(Pixel)组成的,像素是位图最小的信息单元,存储在图像栅格中。 每个像素都具有特定的位置和颜色值。按从左到右、从上到下的顺序来记录图像中每一个像素的信息,如:像素在屏幕上的位置、像素的颜色等。位图图像质量是由单位长度内像素的多少来决定的。单位长度内像素越多,分辨率越高,图像的效果越好。位图也称为“位图图像”“点阵图像”“数据图像”“数码图像”

  • 矢量图是根据几何特性来绘制图形,是用线段和曲线描述图像,矢量可以是一个点或一条线,矢量图只能靠软件生成,矢量图文件占用内在空间较小,因为这种类型的图像文件包含独立的分离图像,可以自由无限制的重新组合;

  • 位图和矢量图的区别

    • 1 最大的区别,矢量图形与分辨率无关,可以将它缩放到任意大小和以任意分辨率在输出设备上打印出来,都不会影响清晰度,而位图是由一个一个像素点产生,当放大图像时,像素点也放大了,但每个像素点表示的颜色是单一的,所以在位图放大后就会出现咱们平时所见到的马赛克状。

    • 2 位图表现的色彩比较丰富,可以表现出色彩丰富的图象,可逼真表现自然界各类实物;而矢量图形色彩不丰富,无法表现逼真的实物,矢量图常常用来表示标识、图标、Logo等简单直接的图像。

    • 3 由于位图表现的色彩比较丰富,所以占用的空间会很大,颜色信息越多,占用空间越大,图像越清晰,占用空间越大;由于矢量图形表现的图像颜色比较单一,所以所占用的空间会很小。

    • 4 经过软件矢量图可以很轻松的转化为位图,而位图要想转换为矢量图必须经过复杂而庞大的数据处理,而且生成的矢量图质量也会有很大的出入。

    • 5 位图的文件类型很多,如.bmp、.pcx、.gif、.jpg、.tif、photoshop的.psd等;

      矢量图形格式也很多,如AdobeIllustrator的.AI、.EPS和SVG、AutoCAD的.dwg和dxf、Corel DRAW的.cdr等。

  • 设备像素比(device pixel ratio) 定义了物理像素和设备独立像素的对应关系

    dpr = 物理像素/css像素 (x 和 y方向上都是如此),可以通过window.devicePixelRatio属性获取当前设备的dpr

  • 比如iphone设备宽高 375x667,那么此时设备独立像素(css像素)就是375x667;

    • 对于普通屏幕物理像素 375x667; 即一个css像素对应一个物理像素
    • 对于retina屏幕(dpr=2)物理像素 750x1334;即一个css像素对应4个物理像素(x,y方向都进行了等比缩放)

5 对于图片高清显示的问题

最完美的显示情况是一个位图像素对应一个物理像素,图片才能完美的显示

  • 对于普通屏幕 ,200x300的位图在普通屏幕上显示是没有问题的
  • 对于retina屏幕(dpr = 2),200x300的位图在retina屏幕上显示的时候,位图像素的一个像素对应了4个物理像素(x,y方向都会进行缩放);所以会导致图片模糊,为什么会导致图片模糊呢?
  • 那么对于单个位图像素不能再进行分割,然后多余的物理像素会进行就近取色,所导致图片模糊

那么这个问题如何解决呢?

根本实现,让一个位图像素对应一个物理像素

实现方法 1 提供400x600的位图 2 img标签的宽高设置为 200x300

如此一来,在retina屏幕下,位图像素的在img标签下,一个位图像素对应一个物理像素

但是问题又来了,如果 1 提供400x600的位图 2 img标签的宽高设置为 200x300

如此在普通屏幕下,这个时候,一个物理像素对应了四个位图像素,图片显示会模糊?同样,why?

  • 这个时候一个物理像素点的取色同样对应了四个位图像素,所以它的取色只能经过一定的算法(显示的结果就是一张只有原图像素总数的四分之一,我们称这个过程是downsampling),肉眼看上去虽然图片没有特别模糊,但是会少了一些锐利度,或者图片有色差

6 以上对于retina屏幕下图片高清显示 如果图片大小400x600

  • 1 img标签 width : 200 px ; height : 300 px
  • 2 背景图片 width : 200 px ; height : 300 px backgroundground-image : url () ; background-size: 200px 300px (/contain)

###7 这样子也会带来一个新的问题:就是需要准备两套图片,但是还有一个解决方案就是我们只需要准备一套大图,然后需要一个图片服务器,用来处理小图,然后根据不同请求的URL进行下载不同图片

参考