object-fit:封面在 chrome 上提供像素化图像

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

我有一个简单的卡片元素,里面有一个

<img>
标签。该图像具有
object-fit: cover;
属性。当我使用 Chrome 时,它会产生非常奇怪的像素化效果。另一方面,FireFox 可以毫无问题地绘制图片。这是 chrome 的 bug 还是只是他们的渲染算法不太好?

左边是firefox的图像,右边是chrome的图像,检查手臂和身体。

chrome版本107.0.5304.107 火狐浏览器版本107.0

解决方法是行不通的,因为这只能解决我的问题。 这是另一台电脑上同样的问题。 (不同品牌,不同规格) 问题仍然存在。 (右边是Chrome,仍然检查手臂)

css browser
3个回答
8
投票

TL;DR:你只能减轻这种影响 –
image-rendering
是不可预测的

现状2023-01-18

显然,大多数基于 chromium(blink 引擎)的浏览器(google chrome、opera、vivaldi、brave、ie13/edge 等)会根据所需的缩放/调整大小在不同的插值方法之间切换,以优化渲染性能。

左:内在 3000x3000px 缩小至 240x240px
看起来不错——大概是双线性或双三次插值。

右:内在 4000x3000px 缩小并适合 240x240px
明显的“锯齿状”边缘——大概是一个简单的最近邻插值——通过额外的平移/拟合引入

object-fit:cover

显然,当两者都满足时,基于 chromium 的浏览器将回退到更简单的最近邻下采样方法

  • 内在尺寸和渲染尺寸以及
  • 固有纵横比和渲染纵横比

差异显着。

解决方法:通过优化图像来避免过度调整大小

  • 避免不必要的高分辨率 - 尝试调整图像大小和裁剪图像以匹配实际布局尺寸:例如如果您的图像始终以 1/1 纵横比使用 - 您最好裁剪 16/9 图像。用谷歌灯塔行话来说:“提供适当大小的图像以保存蜂窝数据并缩短加载时间。”
  • 定义响应式图像和/或艺术指导图像候选:
    Smashing 杂志:正确完成响应式图像:和 srcset 指南

但是,上述方法只会减轻这种影响。

希望我们会看到为

image-rendering
值(如
smooth
high-quality
)指定更好的支持/实现。

MDN 网络文档:图像渲染

示例片段(仅用于比较/测试)

function replaceImg() {
  let images = document.querySelectorAll("img");
  images.forEach((img) => {
    let wNative = img.naturalWidth;
    let hNative = img.naturalHeight;
    let wRendered = img.offsetWidth;
    let hRendered = img.offsetHeight;
    let scale =
      Math.min(...[wRendered, hRendered]) / Math.min(...[wNative, hNative]);

    if (scale < 0.3) {
      scale *= 2;
      (async() => {
        let dataUrl = await imageToDataURL(
          img.src,
          wNative * scale,
          hNative * scale
        );
        img.src = dataUrl;
        img.classList.add("imgDataUrl");
      })();
    }
  });

  async function imageToDataURL(imageUrl, width, height) {
    let img = await fetch(imageUrl);
    img = await img.blob();
    let bitmap = await createImageBitmap(img);
    let canvas = document.querySelector("canvas") ? document.querySelector("canvas") : document.createElement("canvas");
    let ctx = canvas.getContext("2d");
    canvas.width = width;
    canvas.height = height;
    ctx.drawImage(bitmap, 0, 0, width, height);
    let dataUrl = canvas.toDataURL("image/jpeg");
    return dataUrl;
  }
}
* {
  box-sizing: border-box
}

body {
  font-family: sans-serif
}

figure {
  width: 240px;
  height: 240px;
  display: inline-block;
}

img {
  max-width: 100%;
  height: 100%;
  aspect-ratio: 1/1;
  object-fit: cover;
}

.obj-contain {
  object-fit: none;
  object-fit: none;
}

.pixelated {
  image-rendering: pixelated;
}

.crisp {
  image-rendering: crisp-edges;
}

.auto {
  image-rendering: auto;
}

.imgDataUrl {
  outline: 2px solid red;
}
<p><button onclick="replaceImg()"> Replace with dataURL</button></p>


<figure>
  3000 x 3000: auto
  <img class="auto" src="https://picsum.photos/id/76/3000/3000" alt="">
</figure>


<figure>
  4000 x 3000: auto
  <img class="auto" src="https://picsum.photos/id/76/4000/3000" alt="">
</figure>

<figure>
  1200 x 1000: auto
  <img class="auto" src="https://picsum.photos/id/76/1000/800" alt="">
</figure>

<figure>
  240 x 240: auto
  <img class="auto" src="https://picsum.photos/id/76/240/240" alt="">
</figure>

<figure>
  300 x 240: auto
  <img class="auto" src="https://picsum.photos/id/76/300/240" alt="">
</figure>

<figure>
  600 x 480: auto
  <img class="auto" src="https://picsum.photos/id/76/600/480" alt="">
</figure>



<figure>
  3000 x 1500: auto
  <img class="auto" src="https://picsum.photos/id/76/3000/1500" alt="">
</figure>
<figure>
  1600 x 800: auto
  <img class="auto" src="https://picsum.photos/id/76/1600/800" alt="">
</figure>
<figure>
  800 x 400: auto
  <img class="auto" src="https://picsum.photos/id/76/800/400" alt="">
</figure>

<figure>
  600 x 300: auto
  <img class="auto" src="https://picsum.photos/id/76/600/300" alt="">
</figure>


<figure>
  800 x 400: pixelated
  <img class="pixelated" src="https://picsum.photos/id/76/600/300" alt="">
</figure>

Codepen 测试示例

»脆度在于情人眼中«

即使困难,也有很多像素插值选项(快速双线性、双三次、lanczos、b 样条、AI/DL 训练算法等)。

公平地说:

  • 一些用户会更喜欢稍微“锯齿状”的边缘而不是稍微“模糊”的边缘
    (琐事:当cleartype和其他字体 引入了抗锯齿技术 – 我很高兴抗锯齿阵线赢得了这场战争......)
  • 后者会抱怨渲染模糊。
    另请参阅解决相反问题的SO问题
  • 其他人 - 使用高像素密度显示器 - 可能根本没有注意到前面提到的“惰性”优化技巧

正如@Rene van der Lende 评论的:
Chromiums 缩小图像渲染本身并不坏 - 有时 Firefox(或 safari 和非 Apple Webkit 浏览器,如 Epiphany 或 midori)可能会遇到类似的问题 但在其他情况下。


0
投票

将此代码添加到您的图像 CSS 中:

变换:translate3d(0px, 0px, 0.1px);

除了像素消失之外,您不会看到差异:-)


0
投票

你应该尝试一下:

溢出剪辑边距:未设置;

溢出:可见;

它对我有用。

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