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.
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)
{
}
}
}
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.
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.
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.
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.
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?
Hi Barry,
Maybe you should contact James South about this. The cropped image is processed by Image Processor.
Dave
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:
The initial cached image is returned unoptimized to reduce time to first byte but subsequent visits to the site will yield an optimized image.
&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.
Hope that helps. :)
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.
My absolute pleasure! :)
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
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
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
is working on a reply...