Image scaling with Java JAI

I need to scale an image using Java JAI. I am currently using the following code:

private static RenderedOp scale(RenderedOp image, float scale) { ParameterBlock scaleParams = new ParameterBlock(); scaleParams.addSource(image); scaleParams.add(scale).add(scale).add(0.0f).add(0.0f); scaleParams.add(Interpolation.getInstance(Interpolation.INTERP_BICUBIC_2)); // Quality related hints when scaling the image RenderingHints scalingHints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); scalingHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); scalingHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); scalingHints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); scalingHints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); scalingHints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); scalingHints.put(JAI.KEY_BORDER_EXTENDER, BorderExtender.createInstance(BorderExtender.BORDER_COPY)); return JAI.create("scale", scaleParams, scalingHints); } 

Unfortunately, this leads to very poor results, especially because I often have to scale images with a scale factor of less than 0.5 ...

Any tips?

+7
java image scaling jai
source share
3 answers

I assume that you are trying to scale a larger image to thumbnail size or to some extent from the original to the scaled image?

In this case, this question was actually addressed by Chris Campbell from Java2D back in 2007 (I did not expect you to know this, just indicating that this is a general question), because the new approaches to scaling Java2D (RenderingHints.VALUE_INTERPOLATION_ *) did not provide equivalent to the previously rejected Image.getScaledInstance (SCALE_AREA_AVERAGING or SCALE_SMOOTH) .

As it turned out, the SCALE_AREA_AVERAGING or SCALE_SMOOTH approaches in the old Java 1.1 approach Image.getScaledInstance were a rather expensive multi-step operation that did a lot of work in the background to create this beautiful image.

Chris noted that the new and β€œright” way to use Java2D to get the same result is a gradual process of scaling the image half and over and over again until the desired image size is reached, preferably such as RenderHints.VALUE_INTERPOLATION_BICUBIC or BILINEAR.

The result is almost identical to the original Image.getScaledInstance approach that people need.

I really went hunting for this answer a few months ago while writing an image placement service and was surprised how complex the simple question was: "How to make a beautiful miniature in Java?" became.

Ultimately, I create a small Java library (Apache 2, open sourced) that implements 3 different approaches to image scaling in Java, using "best practices", including the incremental approach proposed by Chris.

The library is called imgscalr . You can download and use it as simple as:

 BufferedImage thumbnail = Scalr.resize(srcImage, 150); 

There are more options for installation and use (for example, quality or zoom speed), but out of the box there are smart defaults for everything to make a beautiful, scaled image for you, so you don't need to worry about more if you don't want to. The library also makes great efforts to get rid of any distribution of objects that are not absolutely necessary, and immediately get rid of BufferedImage instances if they are not needed - this is code as part of a long-term server application, so this was critical.

I have already made several releases of the library, and if you prefer to just tear out the "good stuff" and do something with it yourself, go for it. It's all on GitHub , and none of this is a secret, just an attempt to make life easier for people.

Hope this helps.

+15
source share

I got good results with the Thumbnailator . I don't know what JAI.KEY_BORDER_EXTENDER should do, but I believe that the rest of the functionality (anti-aliasing, anti-aliasing, etc.) is supported. I used it to create grayscale thumbnails with fairly large black and white images

+3
source share

If you are lucky and you only have black and white images, you can use very fast and high-quality work: SubsampleBinaryToGray

+1
source share

All Articles