解决“图片因为CSS样式缩放导致变糊问题”
对于图片的放大缩小,我们都会自然而然的认为:图片放大,会变得模糊,图片变小会变得较为清晰。放大,会把瑕疵更明显的暴露出来;缩小,可以让瑕疵难以发觉。这是生活中的自然现象。但是,这个现象放到网页上的图片就“变了味”。
前言
对于图片的放大缩小,我们都会自然而然的认为:图片放大,会变得模糊,图片变小会变得较为清晰。放大,会把瑕疵更明显的暴露出来;缩小,可以让瑕疵难以发觉。这是生活中的自然现象。但是,这个现象放到网页上的图片就“变了味”。
变成什么“味”了呢?
通过CSS样式对图片做等比例的放大缩小操作,图片都会变模糊,和通过滚轮对图片做放大缩小操作差异很大。
问题演示
假设有这样一张图:
通过win11的“图片”软件对其放大缩小。
通过编写HTML将三者在浏览器中显示。
代码:
<div style="text-align: center">
<img src="/image_600px.png" />
<img src="/image.png" />
<img src="/image_300px.png" />
</div>
结果如下:
接下来,通过CSS样式调整中间原图的大小。
可以看到,无论是放大还是缩小,中间的原图都变模糊了。从这里我们可以推断出,在浏览器通过CSS的样式对图片做放大缩小操作是不同于专门的图片处理软件的。其效果远不如专门的图片软件处理结果好。
但是在网页上使用图片时是无法避免CSS样式对图片进行放大缩小的(我们总不能为每个尺寸都设置相应的图片吧!)。对于这个问题,前端可以通过CSS样式属性image-rendering
来优化。
前端的优化方法 —— image-rendering
在网页上通过CSS样式对图片进行缩放从而导致图片模糊,究其原因是因为浏览器的缩放算法和图片处理软件的不同导致的差异。所以,要解决这个问题,就需要优化浏览器的缩放算法。CSS属性image-rendering
正是为此而存在的。
image-rendering
CSS 属性
image-rendering
用于设置图像缩放算法。它适用于元素本身,适用于元素其他属性中的图像,也应用于子元素。举个例子,如果有一张尺寸为
100×100px
的图片,但作者有意将尺寸设置为200×200px
(或50×50px
),然后,图片便会根据image-rendering
指定的算法,缩小或放大到新尺寸。此属性对于未缩放的图像没有影响。截取自——《MDN——image-rendering》
image-rendering
可选属性值如下表:
属性值 | 说明 |
---|---|
auto | 自 Gecko 1.9 (Firefox 3.0)起,Gecko 使用双线性(bilinear)算法进行重新采样(高质量)。 |
crisp-edges | 必须使用可有效保留对比度和图像中的边缘的算法来对图像进行缩放,并且,该算法既不会平滑颜色,又不会在处理过程中为图像引入模糊。合适的算法包括最近邻居(nearest-neighbor)算法和其他非平滑缩放算法,比如 2×SaI 和 hqx-* 系列算法。此属性值适用于像素艺术作品,例如一些网页游戏中的图像。 |
pixelated | 放大图像时, 使用最近邻居算法,因此,图像看着像是由大块像素组成的。缩小图像时,算法与 auto 相同。 |
auto
是浏览器默认的缩放算法;放大图像时,crisp-edges
的效果和auto
一致,缩小时,crisp-edges
的效果比auto
更好;如果设置了pixelated
,无论放大还是缩小图像,看起来都比auto
更明亮了,只不过锯齿也高了。
设置crisp-edges
的效果图:
设置 pixelated
的效果图:
crisp-edges
属性说明:大多数浏览器不再支持
image-rendering: crisp-edges;
这种写法了。需要通过非标准写法来实现设置,兼容性写法如下:.crisp-edges { image-rendering: -moz-crisp-edges; image-rendering: -o-crisp-edges; image-rendering: -webkit-optimize-contrast; image-rendering: crisp-edges; -ms-interpolation-mode: nearest-neighbor; }
image-rendering
兼容性问题:
和其他CSS属性一样,image-rendering
存在浏览器兼容性问题。例如 IE 就没有支持该属性。
有关兼容性的更多资讯,请查看:“image-rendering” | Can I use… Support tables for HTML5, CSS3, etc
后端的优化方法
尽管借助image-rendering
可以降低浏览器对图像缩放的影响。但是因为浏览器支持问题,这种方式或多或少存在着隐患——不同的浏览器显示效果不一致。因此,为了保证图片的在不同浏览器的保持一致。我们就不能在浏览器上通过CSS对图像做缩放操作。换而言之就是服务器提供不同尺寸的图片。
这要怎么做呢?同样的图片上传不同尺寸到服务器?这是非常吃力不讨好的事情,显然不能成为可行的方案。
正确的做法应该是,服务器存储一张原图,然后根据请求参数的不同导出不同尺寸的图片,再传输给前端。
具体实现过程属于后端范畴,这里就不展开了(我也不会呀!( ̄y▽, ̄)╭ )。
提供一个思路:可使用imgproxy来实现。
相关文档:
后记
以上仅为个人见解,如有不足欢迎指正。
如果您有更好的处理方法,但求指点一二!
参考文献
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)