Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this image look so bad after being scaled down in Java?

Here is the original image: http://rank.my/public/images/uploaded/orig-4193395691714613396.png

And here it is scaled down to 300x225:

http://rank.my/public/images/uploaded/norm-4193395691714613396.png

And here it is scaled down to 150x112:

http://rank.my/public/images/uploaded/small-4193395691714613396.png

As you can see, 300x225 looks pretty bad, and 150x112 looks awful. Here is the code I'm using to scale down the image:

private static BufferedImage createResizedCopy(final BufferedImage source, final int destWidth,
        final int destHeight) {
    final BufferedImage resized = new BufferedImage(destWidth, destHeight, source.getType());
    final Graphics2D bg = resized.createGraphics();
    bg.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    bg.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    bg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    final float sx = (float) destWidth / source.getWidth();
    final float sy = (float) destHeight / source.getHeight();
    bg.scale(sx, sy);
    bg.drawImage(source, 0, 0, null);
    bg.dispose();
    return resized;
}

What am I doing wrong here? The image scaling doesn't have to be especially fast, quality is definitely a priority over speed. Am I using the wrong technique?

like image 815
sanity Avatar asked Feb 11 '11 02:02

sanity


People also ask

What does scaling do to an image?

When scaling, the resolution is not adjusted to best suit the new size, rather the pixels are stretched and can appear pixelated. The most common side effect of scaling an image larger than its original dimensions is that the image may appear to be very fuzzy or pixelated.

How do you change the size of an image in Java?

getScaledInstance() You can resize an image in Java using the getScaledInstance() function, available in the Java Image class. We'll use the BufferedImage class that extends the basic Image class.

What is a Java image?

Image class in Java is an abstract superclass for all the other classes used for graphical image representation.


2 Answers

There are three ways to fix the downscaling problem. First is to do it in multiple steps, with no more than a 75% reduction in each step. The second is to blur the image before resizing; the more it shrinks, the more you'll have to blur. The third way is to use a method that filters using more than the 2x2 to 4x4 pixel blocks used by a naive bilinear or bicubic interpolation method. As the shrink factor grows larger, so should the pixel block used by the filter, otherwise you get aliasing artifacts as you've seen here.

like image 156
Mark Ransom Avatar answered Sep 28 '22 23:09

Mark Ransom


I've never used these libraries so I feel unqualified to answer, but I can't help but pass along these links I found that I think may be useful. Hopefully this will help.

http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html

http://www.componenthouse.com/article-20

like image 34
Ryan Thames Avatar answered Sep 28 '22 22:09

Ryan Thames