分享几种适配方案,供大家参考。
1. <img>标签引用的图片
我们以一张 300*200px 的照片为例:
1
<img src="./photo.jpg" style="width:300pxheight:200px" />
如果想让这张图片在 Retina 屏幕下达到应有的显示分辨率,只需使用该照片的源文件导出一张清晰的 600*400px 的图片,我们将其命名为 photo@2x.jpg,替换现有的图片即可:
1
<img src="./photo@2x.jpg" style="width:300pxheight:200px" />
换成 @2X 图片,在 Retina 屏幕下的显示就清晰多了,可谓细节毕现。不过在普通屏幕下,图片的显示需要经过浏览器的压缩,一些老版本浏览器如 IE6、7 会显示得非常失真,同时大尺寸的图片会占用更多的带宽,增加页面加载的时间,降低用户体验。通过 JS 的辅助,可以让图片在普通屏幕和 Retina 屏幕下做到自动适配:
<img class="photo" src="./photo.jpg" style="width:300pxheight:200px" /> <script type="text/javascript">$(document).ready(function () {
if (window.devicePixelRatio >1) {
var images = $("img.photo")
images.each(function(i) {
var x1 = $(this).attr('src')
var x2 = x1.replace(/(.*)(\.\w+)/, "$1@2x$2")
$(this).attr('src', x2)
})
}
})</script>
Retina.js 提供了更加完善的解决方案,自动匹配屏幕分辨率的同时,还可以检测服务器上是否存有当前图片的 @2X 版本,以决定是否替换。
优点:
操作简单
普通屏幕下不会加载 @2X 的大尺寸图片,节约带宽
缺点:
Retina 屏幕下,标准图片和 @2X 图片都会被加载
图片在显示过程中会被重绘
有些老版本浏览器下存在兼容问题
2. CSS 背景图片
2.1 Meta Queries + background-size
我们以一张 logo 的背景图为例,首先我们定义 logo 的尺寸为 100*40px,然后为 #logo 设定一个 100*40px 的背景图片 logo.png,
#logo {
width: 100px
height: 40px
background: url(./logo.png) 0 0 no-repeat}
接下来通过 Meta Queries 判断设备的最小显示像素比,如果大于等于1.5的话,为 #logo 设定一张 200*80px 的背景图片 logo@2x.png,然后通过设置 background-size 让背景图显示为 logo 该有的尺寸。这里的显示像素比我们选择 1.5 作为阈值,是为了适配除苹果以外的高分辨率设备,比如三星的 Android Pad。
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (min--moz-device-pixel-ratio: 1.5), /* 注意这里的写法比较特殊 */
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (min-device-pixel-ratio: 1.5) {
#logo {
background-image: url(./logo@2x.png)
background-size: 100px auto
}}
这样,对于普通的显示设备或是不支持 Meta Queries 的浏览器,会显示标准的背景图,对于支持 Meta Queries 的 Retina 设备,会显示 @2X 的背景图。( IE6、7、8 均不支持 Meta Queries 和 background-size )
如果仅是为了适配当前的苹果 Retina 显示屏,也可以直接判断设备的显示像素比是否等于2:
@media only screen and (-webkit-device-pixel-ratio: 2),
only screen and (-moz-device-pixel-ratio: 2),
only screen and (-o-device-pixel-ratio: 2/1),
only screen and (device-pixel-ratio: 2) {
...}
优点:
只会加载匹配当前设备的最适图片
跨浏览器兼容
缺点:
如果背景图片很多的话,需要编写非常冗长的代码
2.2 image-set
我们同样以之前的 logo 为例,实现方式如下:
#logo {
background: url(./logo.png) 0 0 no-repeat
background-image: -webkit-image-set(url(./logo.png) 1x, url(./logo@2x.png) 2x)}
优点:
让图片的链接地址在 CSS 中更加集中,代码的维护成本降低
可以让浏览器获取多种尺寸的图片文件,根据屏幕分辨率或是其他一些因素选择适当的图片进行展示,在图片的匹配上可以做到更加智能
缺点:
image-set 现在只是 CSS4 的一个草案,目前只有 Webkit 内核的 Safari 6+ 和 Chrome 21+ 支持该属性
最后的这条缺点很致命,期待 W3C 早日将 image-set 写入标准之中,让更多的浏览器支持这种写法。
3. 使用 SVG 可缩放矢量图形
与只能记录像素信息的位图相比,矢量图在不同分辨率下的适配有着先天的优势,目前大多数现代浏览器都已经支持基于 XML 的 SVG 格式图形的显示,网页中一些线条简单的 Logo 、图标或特殊字形,如果转成矢量的 SVG 格式来显示,在 Retina 屏下的适配也就搞定了。
制作 SVG 格式图片,可以使用 Adobe Illustrator 或免费的替代软件 inkscape 。
使用 SVG 格式图片,可以像我们使用其他格式的图片一样,用 HTML 的 <img>标签引用,或用 CSS 的 background-image 、 content:url() 属性,需要注意的是,无论用哪种形式,最好定义一下图片的尺寸。
1
<img src="example.svg" width="300" height="200" />
/* Using background-image */.image {
background-image: url(example.svg)
background-size: 300px 200px
width: 300px
height: 200px} /* Using content:url() */.image-container:before {
content: url(example.svg)
/* width and height do not work with content:url() */}
如果需要兼容 IE6、7、8 或是其他一些不支持 SVG 的浏览器,需要额外用到 PNG 格式的图片副本(关于 PNG 格式 Alpha 通道的兼容问题这里不做讨论)。
3.1 <img>标签引用 SVG 格式图片
在 HTML 的 <img>标签中,增加一个 PNG 格式图片的自定义属性
1
<img src="example.svg" data-png-fallback="example.png" />
然后引入 jQuery 和 Modernizr 判断当前浏览器是否支持 SVG ,不支持的话使用 PNG 替换 SVG 。
$(document).ready(function(){
if(!Modernizr.svg) {
var images = $('img[data-png-fallback]')
images.each(function(i) {
$(this).attr('src', $(this).data('png-fallback'))
})
}})
3.2 CSS 背景引用 SVG 格式图片
引入 Modernizr ,将 CSS 改写成以下形式即可:
.image {
background-image: url(example.png)
background-size: 30p0x 200px} .svg {
.image {
background-image: url(example.svg)
}}
为了获得最佳的跨浏览器兼容效果,避免在 Firefox 和 Opera 下出现光栅问题,制作的 SVG 图片最小要达到父容器的尺寸。
优点:
可以适配任意分辨率
维护成本较低
矢量图可以无限伸缩,更加面向未来
缺点:
不适合复杂的图形,复杂的矢量图形可能会导致文件过大
不同的抗锯齿算法,可能会带来不同的浏览感受
IE6、7、8,早期的 Android 浏览器,及其他一些较老的浏览器无法提供对 SVG 的原生支持,使用 <img>标签的方式可能会导致浏览器下载 SVG 文件
4. Favicon
Favicon 的 Retina 适配比较容易,或许你的现在 Favicon 在 Retina 下就已经显示得非常清晰,如果不是这样,使用 ico 编辑工具,创建一个包含 16*16 和 32*32 两种内建图像的 ico 文件,替换现有的 Favicon 即可,浏览器会根据分辨率的大小自动匹配内建图像的尺寸。
至于 ico 编辑工具,Windows 下推荐使用 IconXP ,Mac 下推荐 Apple’s Icon Composer(Graphic Tools in Xcode 中)。
Retina屏幕将原有的1个像素再拆分成4个像素,也就是2*2,相当于大了1倍。举个例子:
15寸 RMBP,分辨率是2880*1800,实际显示的界面内容是1440*900。
因此你原来100像素的东西,在 Retina 屏幕的机器上看,实际占用了200像素。
一dpi
dpi 、 dip 、分辨率、屏幕尺寸、px、density 关系以及换算
qdgithub
转载
关注
1点赞·3799人阅读
基本概念
分辨率
横纵两个方向的像素点的数量,常见取值480X800,320X480
屏幕尺寸
屏幕对角线的长度,电脑电视同理。
屏幕比例的问题
因为只确定了对角线长,2边长度还不一定,所以有了4:3,16:9这种,这样就可以算出屏幕边长。
物理像素(physical pixel)
一个物理像素是显示器(手机屏幕)上最小的物理显示单元,
在操作系统的调度下,每一个设备像素都有自己的颜色值和亮度。
设备独立像素(density-independent pixel)
设备独立像素(也叫密度无关像素),可以认为是计算机坐标系统中得一个点,
这个点代表一个可以由程序使用的虚拟像素(比如: css像素),然后由相关系统转换为物理像素。
所以说,物理像素和设备独立像素之间存在着一定的对应关系,这就是接下来要说的设备像素比。
设备像素比(device pixel ratio )
设备像素比(简称dpr)定义了物理像素和设备独立像素的对应关系,它的值可以按如下的公式的得到:
设备像素比 = 物理像素 / 设备独立像素 // 在某一方向上,x方向或者y方向
登录后复制
在javascript中,可以通过window.devicePixelRatio获取到当前设备的dpr。
在css中,可以通过-webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio和 -webkit-max-device-pixel-ratio进行媒体查询,对不同dpr的设备,做一些样式适配(这里只针对webkit内核的浏览器和webview)。
以iphone6为例
设备宽高为375×667,可以理解为设备独立像素(或css像素)。
dpr为2,根据上面的计算公式,其物理像素就应该×2,为750×1334。
用一张图来表现,就是这样(原谅我的盗图):
上图中可以看出,对于这样的css样式:
width: 2px
height: 2px
登录后复制
在不同的屏幕上(普通屏幕 vs retina屏幕),css像素所呈现的大小(物理尺寸)是一致的,不同的是1个css像素所对应的物理像素个数是不一致的。
在普通屏幕下,1个css像素 对应 1个物理像素(1:1)。 在retina 屏幕下,1个css像素对应 4个物理像素(1:4)。
位图像素
一个位图像素是栅格图像(如:png, jpg, gif等)最小的数据单元。每一个位图像素都包含着一些自身的显示信息(如:显示位置,颜色值,透明度等)。
谈到这里,就得说一下,retina下图片的展示情况?
理论上,1个位图像素对应于1个物理像素,图片才能得到完美清晰的展示。
在普通屏幕下是没有问题的,但是在retina屏幕下就会出现位图像素点不够,从而导致图片模糊的情况。
用一张图来表示:
如上图:对于dpr=2的retina屏幕而言,1个位图像素对应于4个物理像素,由于单个位图像素不可以再进一步分割,所以只能就近取色,从而导致图片模糊(注意上述的几个颜色值)。
所以,对于图片高清问题,比较好的方案就是两倍图片(@2x)。
如:200×300(css pixel)img标签,就需要提供400×600的图片。
如此一来,位图像素点个数就是原来的4倍,在retina屏幕下,位图像素点个数就可以跟物理像素点个数形成 1 : 1的比例,图片自然就清晰了(这也解释了之前留下的一个问题,为啥视觉稿的画布大小要×2?)。
很明显,在普通屏幕下,200×300(css pixel)img标签,所对应的物理像素个数就是200×300个,而两倍图片的位图像素个数则是200×300*4,所以就出现一个物理像素点对应4个位图像素点,所以它的取色也只能通过一定的算法(显示结果就是一张只有原图像素总数四分之一,我们称这个过程叫做downsampling),肉眼看上去虽然图片不会模糊,但是会觉得图片缺少一些锐利度,或者是有点色差(但还是可以接受的)。
用一张图片来表示:
几个问题
这里说一下,移动端H5开发,在不同分辨率,不同屏幕手机下会遇到的几个经典问题。
retina下,图片高清问题
这个问题上面已经介绍过解决方案了:两倍图片(@2x),然后图片容器缩小50%
如:图片大小,400×600
1.img标签
width: 200px
height: 300px
登录后复制
2.背景图片
width: 200px
height: 300px
background-image: url(image@2x.jpg)
background-size: 200px 300px// 或者: background-size: contain
登录后复制
这样的缺点,很明显,普通屏幕下:
同样下载了@2x的图片,造成资源浪费。
图片由于downsampling,会失去了一些锐利度(或是色差)。
所以最好的解决办法是:不同的dpr下,加载不同的尺寸的图片。
不管是通过css媒体查询,还是通过javascript条件判断都是可以的
那么问题来了,这样的话,不就是要准备两套图片了嘛?(@1x 和@2x)
我想,做的好的公司,都会有这么一个图片服务器,通过url获取参数,
然后可以控制图片质量,也可以将图片裁剪成不同的尺寸。
所以我们只需上传大图(@2x),其余小图都交给图片服务器处理,我们只要负责拼接url即可。
如,这样一张原图:
https://img.alicdn.com/tps/TB1AGMmIpXXXXafXpXXXXXXXXXX.jpg // 原图
登录后复制
可以类似这样,进行图片裁剪:
// 200×200
https://img.alicdn.com/tps/TB1AGMmIpXXXXafXpXXXXXXXXXX.jpg_200x200.jpg
// 100×100
https://img.alicdn.com/tps/TB1AGMmIpXXXXafXpXXXXXXXXXX.jpg_100x100.jpg
(ps: 当然裁剪只是对原图的等比裁剪,得保证图片的清晰嘛~)
登录后复制
原文地址:移动端高清、多屏适配方案
二
百度知道
分辨率和dpi的换算是什么?
查看全部1个回答
教育能手H
高能答主
专注教育,寓教于春风细雨
关注
成为第728位粉丝
分辨率和dpi的换算如下:
比如一个机器,屏幕4寸,分辨率480X800,因为不知道边长,肯定不能分开算,4是对角线长度,那直接用勾股定理算对角线像素,除以4,算出来大概是 dpi = 233 像素/英寸。
分辨率,指的是图像或者显示屏在长和宽上各自拥有的像素个数。比如照片分辨率为1920x1080,意思是这张照片是由横向1920个像素点和纵向1080个像素点构成,一共包含了1920x1080个像素点。
定义:
当我们需要鼠标在屏幕上移动一段固定的距离时,高DPI的鼠标所移动的物理距离会比低DPI鼠标要短。高DPI的鼠标,往往只需要移动很小一点距离,就能够将光标从屏幕的一侧边缘移动到屏幕的另一边。而低DPI的鼠标,完成这一操作,往往需要移动超过高DPI鼠标数倍的距离。