Today marks another big ImageProcessor release, and my first antipodean one - There's a lot going on so here's a run through of new functionality that's been added to Imageprocessor v2.4 and ImageProcessor.Web. v4.4
This method allows you to change the resolution of the given image.
public ImageFactory Resolution(int horizontal, int vertical, PropertyTagResolutionUnit unit = PropertyTagResolutionUnit.Inch)
If any EXIF data is to be preserved, the metadata will be updated to match the given resolution.
With this release I've added two new resize modes to the library:
When upscaling an image using this mode the image pixels themselves are not resized, rather the image is padded to fit the given dimensions. When downscaling the image is resized using the rules defined by
ResizeMode.Pad. As with that mode you can recolour the background colour of the padded area for image types without transparency from the default black.
Here's an example resizing the original to 500x500px:
Padded Image With Hot Pink Background
ResizeMode.Crop the position of the image can be anchored to one of nine different anchor points.
This mode looks for the shortest difference in each dimension between the source length and intended length. it will then resize that side to the intended length on the result, the other dimension is resized maintaining the aspect ratio of the original image. Upscaling is disabled in this mode and the original image will be returned if attempted.
Here's an example downscaling a larger version of the original with target dimensions of 500x500px:
I've managed to reduce the memory usage by up to 25% in some circumstances in this version by rewriting the way I ensure certain methods performs their functionality in the correct colour space. These rewrites have also slightly improved the speed on earlier releases which is a nice bonus.
In this release I've ironed out numerous bugs relating to image resolution. EXIF metadata for any method that changes the dimension of the image are now updated also where previously this was overlooked.
This is a big one and I'm very pleased with it...
I'm all about keeping the web lean but the default image encoders in .NET are not that efficient and you can sometimes actually end up with a larger image than what you started with. As such, I've been looking at a way to ensure that anything I output has been optimised as much as possible. For previous versions of ImageProcessor.Web I developed a plugin that post-processed any newly cached images using a variety of tools to reduce the file size as much as possible.
This worked... To a point. Firstly it only worked with the disk cache and not any other cache plugins. Secondly it only acted after the first requests so someone, somewhere would always get an unoptimised image, Thirdly one of the tools I used, optipng was incorrectly detected as malware by Windows Defender.... Not good enough.
As of this version, every image that is processed using ImageProcessor.Web is passed through a series of tools that reduce the output size. This works with whatever cache implementation is used and can dramatically reduce the weight of your pages. This all happens asynchronously and stays snappy so you shouldn't notice any increased processing time.
Here's the built in tools I use so you can check them out:
- gifsicle : http://www.lcdf.org/gifsicle/
- pngout : http://advsys.net/ken/utils.htm#pngout
- pngquant : https://pngquant.org/
- jpegtran : http://jpegclub.org/
It's possible to turn off this behaviour vie the config but you really shouldn't.
There's been various minor little issues I've found and fixed while building this update, one of note though was an issue where prefix values were globally replaced within the request url.
So... What's Next?
For me this release marks the last I shall actively work on in this major version. It might well be the last I do ever depending on what Microsoft do with graphics with the next .NET releases. I've fallen out of love with the open source community a little over the years due to the lack of collaboration I've received on this project and others.
When I started ImageProcessor I didn't know much about images. I was a front end developer who decided to have a go at solving a problem colleagues were struggling with. I'd only been writing C# for a very short while and I was learning as I went on.... I still am.
These libraries are now hugely popular with hundreds of thousands of downloads but the number of people who contribute is still minuscule. If I can write this stuff I guarantee there are a very great number of people out there who could do it and do it better.
I'm very grateful for the work and encouragement of the team at Umbraco for their faith in me and contribution to my code but I feel somewhat that they are alone in doing what they do best in promoting a healthy community around developers.
I'll still fix bugs but I will not add any more new features nor work on making the library cross-platform for now. It's simply too much work for me to do.
Help Me To Help You
If you want to see ImageProcessor continue and you know anyone with the chops to help me or think you can spend an hour a week tinkering away, please get in touch. I'd love to build a v3 as part of a community of developers creating something amazing.
Anyhoo... Enjoy the new releases. As ever you can read about them in the documentation and download them from Nuget.