web-dev-qa-db-fra.com

La mise à l’échelle de l’image entraîne une qualité médiocre dans Firefox / Internet Explorer mais pas chrome

Voir http://jsfiddle.net/aJ333/1/ dans Chrome puis dans Firefox ou Internet Explorer. L'image est à l'origine de 120 pixels, et je suis réduire à 28px, mais il semble mauvais à peu près peu importe ce que vous réduisez à.

L'image est un PNG et possède un canal alpha (transparence).

Voici le code pertinent:

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;
}

Le image-rendering et -ms-interpolation-mode _ Les lignes de CSS ne semblent rien faire, mais je les ai trouvées en ligne tout en faisant des recherches sur le problème.

49
Andrew Rasmussen

Il semble que tu as raison. Aucune option ne permet d’améliorer l’image:
http://www.maxrev.de/html/image-scaling.html

J'ai testé FF14, IE9, OP12 et GC21. Seul le GC a une meilleure mise à l'échelle qui peut être désactivée via image-rendering: -webkit-optimize-contrast. Tous les autres navigateurs n'ont pas/mauvaise mise à l'échelle.

Capture d'écran des différentes sorties: http://www.maxrev.de/files/2012/08/screenshot_interpolation_jquery_animate.png

Mise à jour 2017

Pendant ce temps, d'autres navigateurs prennent en charge la mise à l'échelle en douceur:

  • ME38 (Microsoft Edge) a une bonne mise à l'échelle. Il ne peut pas être désactivé et cela fonctionne pour JPEG et PNG, mais pas pour GIF.

  • FF51 (en ce qui concerne le commentaire de @karthik depuis FF21) a une bonne mise à l’échelle qui peut être désactivée avec les paramètres suivants:

    image-rendering: optimizeQuality
    image-rendering: optimizeSpeed
    image-rendering: -moz-crisp-edges
    

    Remarque: en ce qui concerne MDN le paramètre optimizeQuality est un synonyme pour auto (mais auto ne désactive pas la mise à l'échelle en douceur):

    Les valeurs optimalesQuality et optimSpeed ​​présentes dans la première version (et provenant de son équivalent SVG) sont définies comme des synonymes de la valeur automatique.

  • OP43 se comporte comme GC (ce qui n’est pas surprenant car basé sur Chromium depuis 201 ) et sa toujours cette option qui désactive la mise à l’échelle en douceur:

    image-rendering: -webkit-optimize-contrast
    

Pas de support dans IE9-IE11. Le paramètre -ms-interpolation-mode Ne fonctionnait que dans IE6-IE8, mais était supprimé dans IE9 .

P.S. La mise à l'échelle en douceur est effectuée par défaut. Cela signifie qu'aucune option image-rendering N'est nécessaire!

33
mgutt

Réponse tardive mais cela fonctionne:

/* 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

Voici un autre lien sur le support du navigateur:

https://css-tricks.com/almanac/properties/i/image-rendering/

13
trgraglia

Une façon de "normaliser" l'apparence dans les différents navigateurs consiste à utiliser votre "côté serveur" pour redimensionner l'image. Un exemple utilisant un contrôleur C #:

public ActionResult ResizeImage(string imageUrl, int width)
{
    WebImage wImage = new WebImage(imageUrl);
    wImage = WebImageExtension.Resize(wImage, width);
    return File(wImage.GetBytes(), "image/png");
}

où WebImage est une classe dans System.Web.Helpers.

WebImageExtension est défini ci-dessous:

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());
            }
        }
    }
}

notez l'option InterpolationMode.HighQualityBicubic. C'est la méthode utilisée par Chrome.

Vous devez maintenant publier dans une page Web. Permet d'utiliser le rasoir:

<img src="@Url.Action("ResizeImage", "Controller", new { urlImage = "<url_image>", width = 35 })" />

Et cela a très bien fonctionné pour moi!

Idéalement, il est préférable de sauvegarder l’image au préalable dans différentes largeurs, en utilisant cet algorithme de redimensionnement, afin d’éviter le processus du contrôleur à chaque chargement d’image.

(Désolé pour mon anglais médiocre, je suis brésilien ...)

7
Fernando Teles

Votre problème est que vous utilisez le navigateur pour redimensionner vos images. Les navigateurs ont notoirement de mauvais algorithmes de mise à l'échelle des images, ce qui entraînera la pixellisation laide.

Vous devez redimensionner vos images dans un programme graphique avant de les utiliser sur la page Web.

De plus, vous avez une faute d'orthographe: il faut dire moz-crisp-edge; cependant, cela ne vous aidera pas dans votre cas (car cet algorithme de redimensionnement ne vous donnera pas un redimensionnement de haute qualité: https://developer.mozilla.org/En/CSS/Image-rendering )

4
Timothy Armstrong

Vous devez essayer de conserver un rapport hauteur/largeur approprié entre les tailles que vous souhaitez mettre à l’échelle. Par exemple, si votre taille cible est de 28px, votre taille de source devrait être une puissance de celui-ci, telle que 56 (28 x 2) ou 112 (28 x 4). Cela garantit que vous pouvez évoluer à 50% ou 25% au lieu des 0,233333% que vous utilisez actuellement.

4
Soviut

La mise à l'échelle IE dépend de la quantité de réduction

Certaines personnes ont dit qu'une réduction même des effectifs évitait le problème. Je ne suis pas d'accord.

Dans IE11, je trouve que réduire une image de 50% (par exemple de 300 à 150 pixels) donne un redimensionnement irrégulier (comme si on utilisait le voisin le plus proche). Un redimensionnement à environ 99% ou 73% (par exemple de 300 à 276 pixels) donne une image plus lisse: bilinéaire ou bicubique, etc.

En réponse, j’utilise des images qui ne sont que rétines: peut-être 25% plus gros que ce qui serait utilisé sur un écran de mappage de pixels 1: 1 traditionnel, de sorte que IE ne redimensionne qu’un peu et ne déclenche pas la laideur.

1
David Hoffman

C'est possible! Du moins maintenant que les transformations CSS ont un bon support:

Vous devez utiliser une transformation CSS pour redimensionner l'image. L'astuce consiste à ne pas utiliser uniquement une échelle (), mais également à appliquer une très petite rotation. Cela déclenche IE pour utiliser une interpolation plus douce de l'image:

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);
}
1
James

J'ai vu la même chose dans firefox, la transformation CSS à l'échelle d'un fichier png transparent est très grossière.

J'ai remarqué que lorsque la couleur de fond avait déjà été définie, la qualité était bien meilleure. J'ai donc essayé de définir un fond RGBA avec une valeur d'opacité aussi faible que possible.

background:rgba(255,255,255,0.001);

Cela a fonctionné pour moi, essayez-le.

1
MarkBaillie

Semble Chrome la réduction de l’échelle est la meilleure solution, mais la vraie question est de savoir pourquoi utiliser une image aussi massive sur le Web si vous utilisez une exposition aussi massive. pour les sites Web réactifs, un certain degré de mise à l'échelle est logique, il s'agit en réalité davantage d'une mise à l'échelle que d'une réduction, mais jamais dans une telle échelle.

Il semble que ce soit davantage un problème théorique que Chrome semble régler correctement mais ne devrait pas se produire et ne devrait en fait pas être utilisé dans la pratique, à mon humble avis.

0
Chris