Web端高分屏图片加载方案

4,867 阅读4分钟

前言

随着显示器的快速发展,越来越多的用户更换了高分屏,我们作为Web开发者,网站内的图片尺寸都是适配普通屏幕的,如果在高分屏上图片将会变得模糊不清。

我观察了几个网站,发现他们的做法是直接用了@2x的图片,这种做法在普通屏幕上图片的一些细节会丢失。那么有没有什么办法可以兼顾普通屏幕和高分屏呢?本文就跟大家分享一种解决方案,欢迎各位感兴趣的开发者阅读本文。

基础概念

在前言中,我们提到了高分屏和**@2x**,本章节就跟大家聊一聊这两个概念。

高分屏

高分屏是指高分辨率的显示器,通常情况下我们把大于1080P分辨率的显示器称为高分屏,例如:2k、4k显示器,屏幕分辨率越高,能显示出来的像素点就越多,我们看到的画面也就更细腻。

视频的分辨率

设备像素比

上个章节中,我们讲了高分屏的概念,高分辨率下可以显示更多的像素点,那么操作系统的UI和字体就会变得非常小。

为了解决这个问题,操作系统提供了缩放选项,可以让系统UI看起来跟普通屏一样,但是显示效果更细腻。在macos中,有一个HIDPI的概念,简单来说就是用4个像素渲染1个像素。

如下图所示,我们渲染了圆的1/4,需要4x4个逻辑像素(下图左侧)。如果我们先将画面放大4倍,这个1/4的圆就要对应8x8个逻辑像素了。再将画面渲染到8x8的逻辑像素上(下图中间),最后一一对应的显示到8x8个硬件像素上(下图右侧)。

hidpi-5.png

我们用8x8个硬件像素来渲染一个四分之一的圆,圆的面积依然没有发生改变,但是轮廓处虚化像素的数量变少了、圆的边缘显得更锐利了,肉眼看起来也就更清晰了。

4x4个逻辑像素用8x8个硬件像素来渲染,刚好扩大了2倍,我们把这个比例称为:设备像素比,可以通过window.devicePixelRatio来获取。高分屏上获取到的值就是2,普通屏上获取到的值就是1。因此,我们就需要准备2个尺寸的图片,分别针对普通屏和高分屏。设备像素比是2,我们的图片命名后缀就可以用@2x来标识。

本文只粗略的讲一下HIDPI,想更进一步了解的开发者请移步:谈谈 HiDPI —— 是什么,为什么,怎么做

解决方案

在web端我们要显示一个图片有两种方式:img标签、background-image属性。

img标签

大多数情况下,我们显示一个图片会用src属性,如下所示。

<img src="img/more.png" alt="" style="width: 18px; height: 18px">

在普通屏幕上这个图片看起来很正常,但是在高分屏上就会有些模糊。

image-20220720220139981

我的设备像素比是2,因此我把图片的尺寸扩大2倍,显示出来的效果就是正常的。

<img src="img/more@2x.png" alt="" style="width: 18px; height: 18px" >

image-20220720220403314

如果都用@2x的图片,会造成额外的带宽消耗。有没有什么方法能做到动态加载呢(高分屏用@2x,普通屏用正常图片)?

经过一番查找后,发现img标签有一个名为srcset的属性,它的用法如下所示:

  • 不同尺寸的图片用逗号隔开
  • 每个尺寸的图片路径后跟一个空格写设备像素比(1x、2x)
<img src="img/more.png" alt="" style="width: 18px; height: 18px" srcset="img/more.png 1x,img/more@2x.png 2x">

这样子写了后,浏览器会根据当前屏幕的设备像素比,自动选择要加载的图片,如下所示

  • 普通屏加载1x的图片

image-20220720223135753

  • 高分屏加载2x的图片

image-20220720222819149

background-image属性

css的background-image属性也可以用来显示一张图片,它提供了image-set()方法,会根据当前屏幕的设备像素比,自动选择要加载的图片。它的用法如下所示:

  • image-set方法内部用url来加载图片路径
  • url方法后跟一个空格写设备像素比(1x、2x)
  • -webkit-为兼容写法
<style>
        .img-panel {
            width: 18px;
            height: 18px;
            background-image: image-set(url(./img/more.png) 1x, url(./img/more@2x.png) 2x);
            background-image: -webkit-image-set(url(./img/more.png) 1x, url(./img/more@2x.png) 2x);
        }
    </style>

<body>
    <div class="img-panel"></div>
</body>

同样的,浏览器会根据设备像素比选择合适的图片来加载。

  • 普通屏加载1x的图片

image-20220720225444753

  • 高分屏加载2x的图片

image-20220720225208927

写在最后

至此,文章就分享完毕了。

我是神奇的程序员,一位前端开发工程师。

如果你对我感兴趣,请移步我的个人网站,进一步了解。

  • 文中如有错误,欢迎在评论区指正,如果这篇文章帮到了你,欢迎点赞和关注😊
  • 本文首发于神奇的程序员公众号,未经许可禁止转载💌