У меня есть простой элемент карточки с тегом <img>
внутри. Изображение имеет свойство object-fit: cover;
. Когда я нахожусь в хроме, он имеет очень странный пиксельный эффект. С другой стороны, FireFox рисует картинку без проблем. Это ошибка хрома или просто их алгоритм рендеринга не очень хорош?
слева картинка фаерфокса, справа хрома, проверьте руки и корпус.
хром Версия 107.0.5304.107 фаерфокс версия 107.0
Обходной путь не сработает, так как это будет исправление только с моей стороны. Вот такая же проблема на другом компе. (другой бренд, разные характеристики) Проблема все еще сохраняется. (хром справа, все еще проверяйте руки)
Вы можете попробовать image-rendering
, но это также может быть ошибка на стороне GPU.
изменил вопрос, чтобы ответить на комментарии
Я также пробовал рендеринг изображений, свойства которого в основном устарели или не дают никакого результата.
@AtomicUs5000 Да, GPU работает, но это только на стороне клиента, так что на самом деле проблема не решается.
Вам нужно опубликовать исходное изображение и код, который вы используете, потому что со случайными изображениями разных размеров и минимальным кодом проблема не может быть воспроизведена. Я использую Chrome/Edge и Firefox, все версии 109. x64. Мой тест: Codepen. Вертикальные и изогнутые кабели моста не показывают пикселизацию, на самом деле Chrome сглаживает чуть лучше, чем Firefox. Я позаботился о том, чтобы использовать изображения с высоким контрастом между светлыми и темными цветами.
image-rendering
непредсказуемоСудя по всему, большинство браузеров на основе хрома (blink engine) (google chrome, Opera, Vivaldi, Brave, ie13/edge и т. д.) переключаются между различными методами интерполяции в зависимости от требуемого масштабирования/изменения размера для оптимизации производительности рендеринга.
Слева: внутренний размер 3000 x 3000 пикс. уменьшен до 240 x 240 пикс. Выглядит нормально — предположительно, билинейная или бикубическая интерполяция.
Справа: внутренний размер 4000 x 3000 пикс. уменьшен и вписан в размер 240 x 240 пикс.
Заметные «зубчатые» края — предположительно, простая интерполяция ближайшего соседа — введены дополнительным панорамированием/подгонкой через object-fit:cover
По-видимому, браузеры на основе хрома вернутся к более упрощенному методу понижения частоты дискретизации ближайшего соседа, когда оба
существенно различаются.
Однако вышеупомянутые подходы лишь смягчат этот эффект.
Надеюсь, мы увидим лучшую поддержку/реализацию, как указано для значений 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 для тестирования
Несмотря на сложность, существует множество вариантов интерполяции пикселей (быстрая билинейная, бикубическая, Ланцоша, b-сплайн, алгоритмы, обученные AI/DL и т. д.).
Давайте будем честными:
Как прокомментировал @Rene van der Lende:
Рендеринг изображений с уменьшенным масштабом Chromium сам по себе не является плохим — иногда Firefox (или браузеры Safari и не-Apple WebKit, такие как Epiphany или Midori) могут бороться с аналогичными проблемами, но в других случаях.
Я знал, что это как-то связано с выборкой пикселей вверх/вниз: ближайший сосед/сохранение деталей/сглаживание, как в Photoshop для изменения размера изображений. Что-то должно дать, не так ли? Отсюда моя просьба к ОП о размещении исходного изображения. Кстати, в некоторых случаях у Firefox тоже есть свои проблемы... Вы получили мой голос!😉
Спасибо! Боюсь, у нас никогда не будет более надежных вариантов рендеринга. Список параметров, похожий на Photoshop, действительно был бы намного более интуитивным (например, «нет», «ближайший сосед», «биллинейный», «бикубический» и т. д.) «-webkit-optimize-contrast» — мое любимое семантическое зверство.
Вы пробовали: stackoverflow.com/questions/71251416/…?