html - w3schools - El escalado de la imagen causa una baja calidad en Firefox/Internet Explorer, pero no en Chrome
image rendering w3schools (10)
Ver http://jsfiddle.net/aJ333/1/ en Chrome y luego en Firefox o Internet Explorer. La imagen es originalmente 120px, y estoy reduciendo a 28px, pero se ve bastante mal, no importa a qué lo reduzcas.
La imagen es un PNG y tiene un canal alfa (transparencia).
Aquí está el código relevante:
HTML:
<a href="http://tinypic.com?ref=2z5jbtg" target="_blank">
<img src="http://i44.tinypic.com/2z5jbtg.png" border="0" alt="Image and video hosting by TinyPic">
</a>
CSS:
a {
width: 28px;
height: 28px;
display: block;
}
img {
max-width: 100%;
max-height: 100%;
image-rendering: -moz-crisp-edges;
-ms-interpolation-mode: bicubic;
}
Las líneas de image-rendering
-ms-interpolation-mode
y -ms-interpolation-mode
de CSS no parecían hacer nada, pero las encontré en línea mientras investigaba el problema.
IE Scaling depende de la cantidad de Downsize
Algunas personas dijeron que una reducción de fracción par evita el problema. Estoy en desacuerdo.
En IE11 me parece que reducir una imagen en un 50% (por ejemplo, 300px a 150px) produce un cambio de tamaño irregular (como si estuviera usando el vecino más cercano). Un cambio de tamaño a ~ 99% o 73% (por ejemplo, 300px a 276px) produce una imagen más suave: bilineal o bicúbica, etc.
En respuesta, he estado usando imágenes que son simplemente retina-ish: tal vez un 25% más grandes que las que se usarían en una pantalla tradicional de mapeo de 1: 1 píxeles, por lo que IE solo cambia el tamaño un poco y no desencadena la fealdad.
¡Esto es posible! Al menos ahora que las transformaciones de CSS tienen un buen soporte:
Necesita usar una transformación CSS para escalar la imagen; el truco no es solo usar una escala (), sino también aplicar una rotación muy pequeña. Esto activa IE para usar una interpolación más suave de la imagen:
img {
/* double desired size */
width: 56px;
height: 56px;
/* margins to reduce layout size to match the transformed size */
margin: -14px -14px -14px -14px;
/* transform to scale with smooth interpolation: */
transform: scale(0.5) rotate(0.1deg);
}
Debería intentar mantener una relación de aspecto adecuada entre los tamaños desde los que escala desde y hasta. Por ejemplo, si su tamaño objetivo es 28px, su tamaño de fuente debería ser una potencia de eso, como 56 (28 x 2) o 112 (28 x 4). Esto asegura que puede escalar en un 50% o 25% en lugar del 0.233333% que está usando actualmente.
He visto lo mismo en Firefox, css transform a escala transparente png se ve muy duro.
Noté que cuando tenían un conjunto de colores de fondo, la calidad era mucho mejor, así que intenté establecer un fondo RGBA con un valor de opacidad tan bajo como fuera posible.
background:rgba(255,255,255,0.001);
Esto funcionó para mí, pruébalo.
Parece que la reducción de escala de Chrome es la mejor, pero la verdadera pregunta es ¿por qué usar una imagen tan masiva en la web si usas show es tan escalada? Los tiempos de descarga que se muestran en la página de prueba anterior son terribles. Especialmente para sitios web con capacidad de respuesta, una cierta cantidad de escalado tiene sentido, en realidad es más una escala que una escala reducida. Pero nunca en tal escala (perdón).
Parece que esto es más un problema teórico que Chrome parece tratar muy bien, pero en realidad no debería suceder y en realidad no debería utilizarse en la práctica en mi humilde opinión.
Parece que tienes razón. Ninguna opción escala la imagen mejor:
http://www.maxrev.de/html/image-scaling.html
He probado FF14, IE9, OP12 y GC21. Solo GC tiene una mejor escala que se puede desactivar a través image-rendering: -webkit-optimize-contrast
. Todos los demás navegadores no tienen escalas / pobres.
Captura de pantalla de la salida diferente: http://www.maxrev.de/files/2012/08/screenshot_interpolation_jquery_animate.png
Actualización 2017
Mientras tanto, algunos navegadores más admiten escala suave:
ME38 (Microsoft Edge) tiene una buena escala. No se puede desactivar y funciona para JPEG y PNG, pero no para GIF.
FF51 (Respecto al comentario de @karthik desde FF21) tiene una buena escala que se puede deshabilitar mediante las siguientes configuraciones:
image-rendering: optimizeQuality image-rendering: optimizeSpeed image-rendering: -moz-crisp-edges
Nota: Con respecto a MDN, la configuración
optimizeQuality
es un sinónimo deauto
(pero elauto
no deshabilita la escala suave):Los valores optimizeQuality y optimizeSpeed presentes en el borrador inicial (y procedentes de su contraparte SVG) se definen como sinónimos para el valor automático.
OP43 se comporta como GC (no es sorprendente, ya que está basado en Chromium desde 2013 ) y sigue siendo esta opción que desactiva la escala suave:
image-rendering: -webkit-optimize-contrast
Sin soporte en IE9-IE11. La -ms-interpolation-mode
solo funcionaba en IE6-IE8, pero se eliminó en IE9 .
PS La escala suave se realiza de forma predeterminada. ¡Esto significa que no se necesita ninguna opción de image-rendering
!
Recuerde que los tamaños en la web están aumentando drásticamente. Hace 3 años, realicé una revisión para que nuestro diseño de sitio de 500 px fuera 1000. Ahora, donde muchos sitios están haciendo el salto a 1200, pasamos de eso y llegamos a un máximo de 2560 optimizado para 1600 de ancho (o 80% dependiendo en el nivel de contenido) área de contenido principal con capacidad de respuesta para permitir las mismas proporciones exactas y apariencia en una computadora portátil (1366x768) y en dispositivos móviles (1280x720 o más pequeños).
El cambio de tamaño dinámico es una parte integral de esto y solo aumentará, por lo que la capacidad de respuesta se vuelve cada vez más importante en 2013.
Mi teléfono inteligente no tiene problemas para tratar el contenido con el cambio de tamaño de 25 elementos en una página, ni el cálculo para cambiar el tamaño ni el ancho de banda. 3 segundos carga la página de nuevo. Se ve muy bien en nuestra laptop de presentación de 6 años (1366x768) y en el proyector (800x600).
Solo en Mozilla Firefox se ve realmente atroz. Incluso se ve bien en IE8 (nunca usado / actualizado desde que lo instalé hace 2.5 años).
Respuesta tardía, pero esto funciona:
/* applies to GIF and PNG images; avoids blurry edges */
img[src$=".gif"], img[src$=".png"] {
image-rendering: -moz-crisp-edges; /* Firefox */
image-rendering: -o-crisp-edges; /* Opera */
image-rendering: -webkit-optimize-contrast;/* Webkit (non-standard naming) */
image-rendering: crisp-edges;
-ms-interpolation-mode: nearest-neighbor; /* IE (non-standard property) */
}
https://developer.mozilla.org/en/docs/Web/CSS/image-rendering
Aquí hay otro enlace que habla sobre el soporte del navegador:
https://css-tricks.com/almanac/properties/i/image-rendering/
Su problema es que confía en el navegador para cambiar el tamaño de sus imágenes. Los navegadores tienen algoritmos de escalado de imagen notoriamente deficientes, que causarán una fea pixelización.
Primero debe cambiar el tamaño de sus imágenes en un programa de gráficos antes de usarlas en la página web.
Además, tienes un error de ortografía: debería decir moz-crisp-edges; sin embargo, eso no lo ayudará en su caso (porque ese algoritmo de cambio de tamaño no le dará un cambio de tamaño de alta calidad: https://developer.mozilla.org/En/CSS/Image-rendering )
Una forma de "normalizar" la apariencia en los diferentes navegadores es usar su "lado del servidor" para cambiar el tamaño de la imagen. Un ejemplo usando un controlador C #:
public ActionResult ResizeImage(string imageUrl, int width)
{
WebImage wImage = new WebImage(imageUrl);
wImage = WebImageExtension.Resize(wImage, width);
return File(wImage.GetBytes(), "image/png");
}
donde WebImage es una clase en System.Web.Helpers.
WebImageExtension se define a continuación:
using System.IO;
using System.Web.Helpers;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Collections.Generic;
public static class WebImageExtension
{
private static readonly IDictionary<string, ImageFormat> TransparencyFormats =
new Dictionary<string, ImageFormat>(StringComparer.OrdinalIgnoreCase) { { "png", ImageFormat.Png }, { "gif", ImageFormat.Gif } };
public static WebImage Resize(this WebImage image, int width)
{
double aspectRatio = (double)image.Width / image.Height;
var height = Convert.ToInt32(width / aspectRatio);
ImageFormat format;
if (!TransparencyFormats.TryGetValue(image.ImageFormat.ToLower(), out format))
{
return image.Resize(width, height);
}
using (Image resizedImage = new Bitmap(width, height))
{
using (var source = new Bitmap(new MemoryStream(image.GetBytes())))
{
using (Graphics g = Graphics.FromImage(resizedImage))
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(source, 0, 0, width, height);
}
}
using (var ms = new MemoryStream())
{
resizedImage.Save(ms, format);
return new WebImage(ms.ToArray());
}
}
}
}
tenga en cuenta la opción InterpolationMode.HighQualityBicubic. Este es el método utilizado por Chrome.
Ahora necesita publicar en una página web. Vamos a usar navaja de afeitar:
<img src="@Url.Action("ResizeImage", "Controller", new { urlImage = "<url_image>", width = 35 })" />
¡Y esto funcionó muy bien para mí!
Lo ideal sería guardar la imagen de antemano en diferentes anchos, utilizando este algoritmo de cambio de tamaño, para evitar el proceso del controlador en cada carga de imagen.
(Lo siento por mi inglés pobre, soy brasileño ...)