imgscalr 4.0 released – Optimal Java Image Scaling

imgscalr is an optimized, fault-tolerant and simple Java library used to resize, rotate, filter, crop or pad images. imgscalr implements the most optimal code-paths for these tasks as recommended by the Java2D team and internally works around a number of hidden JDK and even JVM bugs pertaining to image operations via the Java2D pipeline.

imgscalr 4.0 symbolizes months of reflecting on the use of imgscalr in production in a number of different web and client deployments. With the 4.0 release I wanted to focus on extending the ease-of-use of the Scalr class to include other simple, discrete and commonly-requested image operations like rotation, padding, cropping, etc.

Up until the 4.0 release, imgscalr was slowly overloading the use of the resize methods by adding more and more variants of the methods including support for additional features like “resize this image AND rotate it“. This API design doesn’t lend itself to extension as it balloons the number of methods every time a new feature is added.

Instead, I went back to the original mission statement with imgscalr and what made it great: simplicity.

The only way to add new features and keep the API simple was to make the decision that all image operations imgscalr currently (and in the future may) support are considered discrete operations. More specifically, if you resize, you only resize. If you pad an image, you only pad it and so on.

Given this design paradigm, it opened the door for me to add simple graphical operations to imgscalr and ensure that they are performed with the same optimal code-path and automatically avoiding any JDK bugs that might sprout up like imgscalr has done so strongly with image resizing so far.

imgscalr 4.0 is more than a few image operations; I actually re-reviewed all of the code, triaging every code block and every execution path.

There are a slew of changes in the 4.0 release outlined in detail in the changelog, but the highlights are as follows…

Breaking

There were a few breaking changes in the 4.0 release that were required and these decisions were not taken lightly.

  • Package com.thebuzzmedia.imgscalr was changed to org.imgscalr
  • Java 6 is now required due to a JVM 5 bug that segfaults the VM when applying BufferedImageOps
  • Scalr.Rotation enum was rewritten; the previous impl was incorrect and didn’t feature as many rotation options.
  • All resize operations that had previously accepted Rotation were removed; rotate is now a separate discrete operation.
  • AsyncScalr was rewritten to allow for a much cleaner customization via subclassing. Basic customization is even easier with simple system properties. This also avoided potentially nasty memory leaks and bugs with the previous implementation if heavy runtime thread-count customization was used.

New Features

The following are new features in imgscalr 4.0:

  • All discrete image operations also accept an arbitrary number of BufferedImageOps that can be applied to the image after the particular op is done. For example, if you want to resize an image to thumbnail then apply a light anti-aliasing to the image to make it look smoother and then make it grayscale or something along those lines.
  • AsyncScalr now provides support for custom ThreadFactory implementations which can be handy depending on the execution environment; out of the box 2 custom factory implementations are provided for the most common execution environments: DefaultThreadFactory and ServerThreadFactory.
  • apply - Applying BufferedImageOps in Java can be tricky as the Java2D hardware-accelerated pipeline is used and error handling is generally terrible; resulting in either an ImagingOpException to bubble up from the depths of Java2D or return an image that is totally corrupt to the caller. imgscalr works around all the most common failure scenarios to do everything possible to avoid an exception or corrupt image for you when applying arbitrary ops. Even if you are not using imgscalr to resize images, it is recommended you use the apply method to apply any ops you plan on using than just applying them raw using the default JDK API.
  • crop - Simple cropping of images is now supported.
  • pad – Add an equal amount of padding to all sides of an image using any color (including colors with an alpha channel).
  • rotate - Rotate an image using any 90-degree rotation (90, 180 or 270) in addition to being able to flip an image horizontally or vertically.
  • All new operations can be performed asynchronously via AsyncScalr.
  • Mode.FIT_TO_EXACT – After popular demand imgscalr can not fit an image to the exact dimensions given, even if it violates the image’s proportions.
  • A few new pre-defined BufferedImageOps were provided for common image manipulations: OP_GRAYSCALE,OP_BRIGHTER and OP_DARKER.

Overall I am really looking forward to hearing what people think of this release. I’ve tried to get all the good bits that everyone has been asking for into this release in some shape or form while defining an API design style that will be easily extensible in the future with new features without sacrificing the simplicity of imgscalr.

TIP: For a nice usability improvement when leveraging imgscalr in a Java 6+ environment, you can staticly import  the Scalr or AsyncScalr class and write much shorter code like:

import static org.imgscalr.Scalr.*;
 
public void createThumbnail(BufferedImage i) {
  // Create 150x150 thumbnail, apply anti-aliasing filter.
  i = resize(i, 150, OP_ANTIALIAS);
 
  // Pad the result with 4px orange border.
  return pad(i, 4, Color.ORANGE);
}

There is nothing stopping you from just embedding the resize call directly in the pad call, I just split them up for readability.

Tags: , , , , , , , ,

About Riyad Kalla

Software development, video games, writing, reading and anything shiny. I ultimately just want to provide a resource that helps people and if I can't do that, then at least make them laugh.

, , , , , , , ,

3 Responses to “imgscalr 4.0 released – Optimal Java Image Scaling”

  1. digitaljoel November 18, 2011 at 11:02 am #

    This library has saved me a ton of work and I appreciate everything you’ve done on it. I haven’t seen any problems since we upgraded to 3.2. The Async stuff is great for my environment.

    Going to discrete operations is a good idea and should keep it away from the java advanced imaging api that had a single method name with a zillion parameters for determining what operation was actually taking place.

    What are the chances of getting it released to a more public mvn repository?

    • Riyad Kalla November 18, 2011 at 8:47 pm #

      Joel,

      You made my day knowing that the library has helped and thank you for the kind words.

      As for a more public (official) repo, I want to get that done sooner than later. The first step was moving to a pom.xml file for the builds, that is covered by Tommy’s contribution here: https://github.com/thebuzzmedia/imgscalr/pull/58

      The next step is to integrate the migraine-inducing customizations required to do an official release build to the pom.xml itself and that work is being tracked here: https://github.com/thebuzzmedia/imgscalr/issues/41

      I’ll get this work done because I know it is important to a lot of people, it just might be for the 4.1 release.

      • digitaljoel November 18, 2011 at 9:06 pm #

        That’s really great news, I’m excited to see progress on the repo side. That was my one and only concern with the library. What if you decided to go dark one day and unplugged all your computers from the internet and your repo was gone? :) I think having it in an official repo will likely help your adoption rate too because it ads a further (perceived) aire of authenticity and longevity to the releases. Thanks again!

Leave a Reply


4 − 3 =