图像渲染“清晰边缘”与“像素化”

问题描述 投票:0回答:3

根据 MDN,CSS

image-rendering
属性当前建议的值为
auto
crisp-edges
pixelated
。但我看不出
crisp-edges
pixelated
之间的区别,因为两者都应该只是放大像素而不插入任何内容。

那么区别在哪里?

html css image-rendering
3个回答
18
投票

虽然@codl的答案是正确的,但它是不完整的。根据 spec

crisp-edges
pixelated
有两种不同,而不仅仅是一种。

  1. crisp-edges
    允许使用与最近邻算法根本不同的像素缩放算法。其他非平滑像素缩放器的示例包括 hqx 系列和 EPX/Scale2x。但是,
    pixelated
    必须使用最近邻或类似的。

  2. crisp-edges
    适用于放大和缩小,而
    pixelated
    仅适用于放大。它使用与
    auto
    相同的算法进行缩小。

造成这些差异的原因是,

pixelated
是为像素化精灵设计的,即使在大尺寸下也能清晰地像素化,但
crisp-edges
旨在防止图像边缘变得模糊。如果缩小,小精灵会变得模糊,这是可以接受的,因为它看起来像素化程度不会比其原始大小低。使用像素艺术缩放算法确实可以保持清晰的边缘,但它也会减少像素化,这与
pixelated
的设计目的相反。

也就是说,目前建议的

pixelated
用途与精灵无关,而是利用双缩放算法。例如,在 HiDPI 屏幕上,人们普遍认为
auto
放大到正常 DPI 会产生模糊的图标。使用
pixelated
可以让图标放大而不变得模糊,但也可以让它们正常缩小。这允许在纯CSS中使用两种不同的缩放算法,而无需使用JavaScript来检查原始图像的大小或最终显示的大小。


8
投票

根据spec,似乎

crisp-edge
允许平滑的像素艺术缩放算法,如2xSaI和HQ2X;而
pixelated
只允许常见的最近邻缩放。


6
投票

规格于 2021 年 2 月发生变更

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 的方法

  1. 默认(图像渲染:平滑)
  2. 图像渲染:像素化
  3. 图像渲染:边缘清晰
  4. 离线缩放至 256x256,然后使用默认值缩放回 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
更有用。

© www.soinside.com 2019 - 2024. All rights reserved.