根据 MDN,CSS
image-rendering
属性当前建议的值为 auto
、crisp-edges
和 pixelated
。但我看不出 crisp-edges
和 pixelated
之间的区别,因为两者都应该只是放大像素而不插入任何内容。
那么区别在哪里?
虽然@codl的答案是正确的,但它是不完整的。根据 spec,
crisp-edges
和 pixelated
有两种不同,而不仅仅是一种。
crisp-edges
允许使用与最近邻算法根本不同的像素缩放算法。其他非平滑像素缩放器的示例包括 hqx 系列和 EPX/Scale2x。但是,pixelated
必须使用最近邻或类似的。
crisp-edges
适用于放大和缩小,而 pixelated
仅适用于放大。它使用与 auto
相同的算法进行缩小。
造成这些差异的原因是,
pixelated
是为像素化精灵设计的,即使在大尺寸下也能清晰地像素化,但crisp-edges
旨在防止图像边缘变得模糊。如果缩小,小精灵会变得模糊,这是可以接受的,因为它看起来像素化程度不会比其原始大小低。使用像素艺术缩放算法确实可以保持清晰的边缘,但它也会减少像素化,这与 pixelated
的设计目的相反。
也就是说,目前建议的
pixelated
用途与精灵无关,而是利用双缩放算法。例如,在 HiDPI 屏幕上,人们普遍认为 auto
放大到正常 DPI 会产生模糊的图标。使用 pixelated
可以让图标放大而不变得模糊,但也可以让它们正常缩小。这允许在纯CSS中使用两种不同的缩放算法,而无需使用JavaScript来检查原始图像的大小或最终显示的大小。
crisp-edges
现在表示“使用最近邻”,pixelated
表示“保持图像像素化”,可以翻译为“如果您想要做一些比最近邻更好的事情来保持图像像素化”。
当前的现实(2022 年)是,
crisp-edges
(仅在 Firefox 中实现)和 pixelated
(在 Chrome/Edge 和 Safari 中实现)实际上是作为最近邻过滤实现的。
但功能说明:如果您有一个图像,您尝试使用
image-rendering: crisp-edges
放大图像,您的用户可能不会得到您期望的结果。问题是,CSS 在 CSS 像素中工作。 CSS 像素被转换为设备像素。从 CSS 像素到设备像素的转换称为 devicePixelRatio
。 devicePixelRatio
可以是非整数值。
例如,您有 128x128 像素的图像,您希望使用
image-rendering: pixelated
缩放到 256x256,如下所示
<img src="128x128.png" style="width: 256px; height: 256px; image-rendering: pixelated">
并且您认为用户会看到原始图像的每个像素缩放至 2x2。
但是,用户的devicePixelRatio可能不是整数。我的桌面的 devicePixelRatio 是 1.25,这意味着要求
width: 256px; height: 256px;
的样式最终会生成一个 320x320 的设备矩形。 128x128.png 将缩放至 320x320,其中,使用 image-rendering: pixelated
,当实现为 nearest-neighbor
时,意味着某些像素将缩放至 2x2,其他像素将缩放至 1x1。
您可以在此处查看示例。这是一个 64x64.png
这里有 4 种将其缩放 2 倍至 128x128 的方法
.inline {
display: inline-block;
border: 1px solid red;
text-align: center;
padding: 10px;
}
<div class="inline">
<img src="https://i.stack.imgur.com/akzX9.png"
style="width: 128px; height: 128px;">
<div>smooth up</div>
</div>
<div class="inline">
<img src="https://i.stack.imgur.com/akzX9.png"
style="width: 128px; height: 128px; image-rendering: pixelated">
<div>pixelated up</div>
</div>
<div class="inline">
<img src="https://i.stack.imgur.com/akzX9.png"
style="width: 128px; height: 128px; image-rendering: crisp-edges">
<div>crisp up</div>
</div>
<div class="inline">
<img src="https://i.imgur.com/aahR6GT.png"
style="width: 128px; height: 128px;">
<div>smooth down</div>
</div>
<p>zoom in/out with Ctrl/Cmd +/-</p>
如果您运行该代码片段,然后放大浏览器(Ctrl/Cmd +/-),至少在我的机器上,前两个看起来比最后一个差得多。
这里还有一个 在 JavaScript 中缩放的库,它通过确保图像始终缩放到设备像素的倍数来使
image-rendering: pixelated/crisp-edges
更有用。