Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Barry Fogarty 493 posts 1129 karma points
    Apr 09, 2015 @ 05:37
    Barry Fogarty
    1

    ImageCropper returning cropped images with larger file sizes than original

    Not sure if this is an implementation issue but I am finding that if I request a crop of an image, at or around the original size, the returned image is significantly larger (in bytes) than the original.  e.g.

    http://mummycooks.ie/media/1002/slider_photos_01_classes.png?center=0.25628140703517588,0.275&mode=crop&width=915&height=456

    = 827 KB

    http://mummycooks.ie/media/1002/slider_photos_01_classes.png

    = 426 KB

    This happens for JPG images as wll, but to a lesser extent (about 25% larger file sizes).  Is there anything I can do about this?

  • Dave Woestenborghs 3504 posts 12133 karma points MVP 8x admin c-trib
    Apr 09, 2015 @ 07:58
    Dave Woestenborghs
    0

    Hi Barry,

    Maybe you should contact James South about this. The cropped image is processed by Image Processor.

    Dave

  • James Jackson-South 489 posts 1747 karma points c-trib
    Apr 09, 2015 @ 10:54
    James Jackson-South
    109

    Hi Barry,

    Yeah, I have... In PNG's anyway.

    It'll only happen to a JPG if your original image is of lower quality than the output which defaults to 90%. You can change that output adding the &quality= querystring parameter to your request url reduce output size.

    The PNG output size increase is due to .NET not optimizing the output palette as well as they could. To fix this you have two options:

    • Install the ImageProcessor.PostProcessor package via Nuget. This will run embedded tools on the cached image to further reduce the file size.
      The initial cached image is returned unoptimized to reduce time to first byte but subsequent visits to the site will yield an optimized image.
    • Change the format to an indexed png by adding the querystring parameter &format=png8 to your request url.
      This will run the image through a highly optimized quantizer. For most images this will work, but if you have light grey to white gradients, banding will occur.

    If you choose to augment the querystring you can actually automate the process by tapping into one of ImageProcessor.Web's processing events. Here's a full sample of how to do that in Umbraco.

    namespace Your.Namespace
    {
        using ImageProcessor.Web.HttpModules;
    
        using Umbraco.Core;
    
        /// <summary>
        /// Taps into ImageProcessor.Web events to intecept image requests to adjust output quality file size.
        /// </summary>
        public class ImageProcessorInterceptorEventHandler : IApplicationEventHandler
        {
            /// <summary>
            /// Boot-up is completed, this allows you to perform any other boot-up logic required for the application.
            /// Resolution is frozen so now they can be used to resolve instances.
            /// </summary>
            /// <param name="umbracoApplication">The current <see cref="UmbracoApplicationBase"/></param>
            /// <param name="applicationContext">The Umbraco <see cref="ApplicationContext"/> for the current application.</param>
            public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
            {
                // Intercept ImageProcessor requests to alter output quality and file size.
                ImageProcessingModule.OnProcessQuerystring += (sender, args) =>
                {
                    if ((args.RawUrl.Contains(".jpg") || args.RawUrl.Contains(".jpeg")) && !args.Querystring.Contains("quality="))
                    {
                        // 75 is pretty good for web output. You might be able to push it down to 65.
                        return args.Querystring += "&quality=75";
                    }
    
                    if (args.RawUrl.Contains(".png") && !args.Querystring.Contains("format=png8"))
                    {
                        return args.Querystring += "&format=png8";
                    }
    
                    return args.Querystring;
                };
            }
    
            /// <summary>
            /// ApplicationContext is created and other static objects that require initialization have been setup
            /// </summary>
            /// <param name="umbracoApplication">The current <see cref="UmbracoApplicationBase"/></param>
            /// <param name="applicationContext">The Umbraco <see cref="ApplicationContext"/> for the current application.</param>
            public void OnApplicationInitialized(
                UmbracoApplicationBase umbracoApplication,
                ApplicationContext applicationContext)
            {
            }
    
            /// <summary>
            /// All resolvers have been initialized but resolution is not frozen so they can be modified in this method
            /// </summary>
            /// <param name="umbracoApplication">The current <see cref="UmbracoApplicationBase"/></param>
            /// <param name="applicationContext">The Umbraco <see cref="ApplicationContext"/> for the current application.</param>
            public void OnApplicationStarting(
                UmbracoApplicationBase umbracoApplication,
                ApplicationContext applicationContext)
            {
            }
        }
    }
    

    Hope that helps. :)

  • Barry Fogarty 493 posts 1129 karma points
    Apr 09, 2015 @ 14:05
    Barry Fogarty
    1

    Woah.,  Great answer thanks James.  Installing  ImageProcessor.PostProcessor  made a huge difference to both PNG and JPG - it updated the ImageProcessor from 1.9.5 to 2.2, which could have had something to do with it too.  My JPGs are x4 smaller now with that update, and PNGs are working better too.  H5YR, thanks for the awesome package.

  • James Jackson-South 489 posts 1747 karma points c-trib
    Apr 09, 2015 @ 17:52
    James Jackson-South
    2

    My absolute pleasure! :)

  • Keith R Hubbard 175 posts 403 karma points
    Apr 22, 2015 @ 21:19
    Keith R Hubbard
    0

    James

    I wish there was a simple solution like we use to have in v4 and had in damp of v6 for resizing images. With the image cropper in v7 it seems like we spend a lot of time getting images to work correctly. in v4 i used this great and simple image resizer [Image resizer][1]

    [1]: https://our.umbraco.org/projects/developer-tools/image-resizer Daniel Bardi made this project and it was very functional for placing images anywhere. With the cropper we have to work with the focal point and it offsets images. i see the solution about and wonder is there a simple way with image processor i can find in the documentation.

    thanks for your help

    Keith

  • James Jackson-South 489 posts 1747 karma points c-trib
    Apr 22, 2015 @ 23:34
    James Jackson-South
    0

    Hi Keith,

    I understood about half of that and even less why it was relevant to the thread.

    A quick scan of the source code of that package you referenced shows that it uses Image.GetThumbnailImage internally. That method produces low quality thumbnails with no control over quality... Which is what this thread is about. It doesn't offer 99% of the functionality that ImageProcessor does.

    Here's the thing.... Now I apologise if my tone seems harsh but I'm getting kind of fed up with people conflating the two.

    ImageProcessor and ImageProcessor.Web are separate entities to Umbraco. Always have been, always will be. I didn't write the cropper nor know exactly how it works.

    The guys at Umbraco use the ImageProcessor.Web Url API and caching functionality to crop images. That is as close as the two libraries get.

    Now if you are not happy with this then contribute. Everything you are using is free and open source.

    I wrote my libraries to help others and I don't take kindly to people not being appreciative of that effort.

    James

  • Dave Woestenborghs 3504 posts 12133 karma points MVP 8x admin c-trib
    Apr 23, 2015 @ 08:27
    Dave Woestenborghs
    0

    Hi Keith, James,

    I see people often get confused by the cropper. The cropper doesn't resize images, but takes a cuts out small part of your image based on the focal point and the dimensions defined by your crop. Just like in Photoshop where crop and resize are different functions as well.

    If you want to resize your image this can be done in code by using James ImageProcessor. Read the documentation about resizing here : http://imageprocessor.org/imageprocessor-web/imageprocessingmodule/resize/

    The documentation for cropping with ImageProcessor can be found here : http://imageprocessor.org/imageprocessor-web/imageprocessingmodule/crop/

    If you read this you can see the difference between cropping and resizing as well.

    I hope this explains the difference.

    And James just to let you know, I really appreciate the work you have been doing. I owe you a beer at codegarden.

    Dave

Please Sign in or register to post replies

Write your reply to:

Draft