Image scaling causes poor quality in firefox/internet explorer but not chrome

前端 未结 10 1673
一个人的身影
一个人的身影 2020-11-27 03:44

See http://jsfiddle.net/aJ333/1/ in Chrome and then in either Firefox or Internet Explorer. The image is originally 120px, and I\'m scaling down to 28px, but it looks bad pr

相关标签:
10条回答
  • 2020-11-27 04:13

    This is possible! At least now that css transforms have good support:

    You need to use a CSS transform to scale the image - the trick is not just to use a scale(), but also to apply a very small rotation. This triggers IE to use a smoother interpolation of the 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);
    }
    
    0 讨论(0)
  • 2020-11-27 04:14

    Your problem is that you are relying on the browser to resize your images. Browsers have notoriously poor image scaling algorithms, which will cause the ugly pixelization.

    You should resize your images in a graphics program first before you use them on the webpage.

    Also, you have a spelling mistake: it should say moz-crisp-edges; however, that won't help you in your case (because that resizing algorithm won't give you a high quality resize: https://developer.mozilla.org/En/CSS/Image-rendering)

    0 讨论(0)
  • 2020-11-27 04:22

    Late answer but this works:

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

    Here is another link as well which talks about browser support:

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

    0 讨论(0)
  • 2020-11-27 04:23

    It seems that you are right. No option scales the image better:
    http://www.maxrev.de/html/image-scaling.html

    I've tested FF14, IE9, OP12 and GC21. Only GC has a better scaling that can be deactivated through image-rendering: -webkit-optimize-contrast. All other browsers have no/poor scaling.

    Screenshot of the different output: http://www.maxrev.de/files/2012/08/screenshot_interpolation_jquery_animate.png

    Update 2017

    Meanwhile some more browsers support smooth scaling:

    • ME38 (Microsoft Edge) has good scaling. It can't be disabled and it works for JPEG and PNG, but not for GIF.

    • FF51 (Regarding @karthik 's comment since FF21) has good scaling that can be disabled through the following settings:

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

      Note: Regarding MDN the optimizeQuality setting is a synonym for auto (but auto does not disable smooth scaling):

      The values optimizeQuality and optimizeSpeed present in early draft (and coming from its SVG counterpart) are defined as synonyms for the auto value.

    • OP43 behaves like GC (not suprising as it is based on Chromium since 2013) and its still this option that disables smooth scaling:

      image-rendering: -webkit-optimize-contrast
      

    No support in IE9-IE11. The -ms-interpolation-mode setting worked only in IE6-IE8, but was removed in IE9.

    P.S. Smooth scaling is done by default. This means no image-rendering option is needed!

    0 讨论(0)
  • 2020-11-27 04:26

    Remember that sizes on the web are increasing dramatically. 3 years ago, I did an overhaul to bring our 500 px wide site layout to 1000. Now, where many sites are doing the jump to 1200, we jumped past that and went to a 2560 max optimized for 1600 wide (or 80% depending on the content level) main content area with responsiveness to allow the exact same ratios and look and feel on a laptop (1366x768) and on mobile (1280x720 or smaller).

    Dynamic resizing is an integral part of this and will only become more-so as responsiveness becomes more and more important in 2013.

    My smartphone has no trouble dealing with the content with 25 items on a page being resized - neither the computation for resizing nor the bandwidth. 3 seconds loads the page from fresh. Looks great on our 6 year old presentation laptop (1366x768) and on the projector (800x600).

    Only on Mozilla Firefox does it look genuinely atrocious. It even looks just fine on IE8 (never used/updated since I installed it 2.5 years ago).

    0 讨论(0)
  • 2020-11-27 04:29

    One way to "normalize" the appearance in the different browsers is using your "server-side" to resize the image. An example using a C# controller:

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

    where WebImage is a class in System.Web.Helpers.

    WebImageExtension is defined below:

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

    note the option InterpolationMode.HighQualityBicubic. This is the method used by Chrome.

    Now you need publish in a web page. Lets going use razor:

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

    And this worked very fine to me!

    Ideally will be better to save the image beforehand in diferent widths, using this resize algorithm, to avoid the controller process in every image load.

    (Sorry for my poor english, I'm brazilian...)

    0 讨论(0)
提交回复
热议问题