Why does this image look so bad after reduction in Java?

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

And here it is reduced to 300x225:

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

And here it is reduced 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 use to scale 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? Image scaling does not have to be particularly fast; quality is definitely a priority for speed. Am I using the wrong technique?

+5
3

. -, , 75%. -, ; , . - , 2x2 4x4, . , , , .

+5

JAI . , , , , , ImageMagick. ImageMagick , .

, . , RenderingHints.VALUE_RENDER_QUALITY SubsampleAverage, RenderingHints.VALUE_INTERPOLATION_BICUBIC.

JAI . - . PNG, JPEG - , .

,

//Set-up and load file
PlanarImage image = JAI.create("fileload", absPath);
RenderingHints quality = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
Properties p = new Properties(System.getProperties());
p.put("com.sun.media.jai.disableMediaLib", "true");
System.setProperties(p);

//Setup the processes
ParameterBlock pb = new ParameterBlock()
    .addSource(image)
    .add(scaleX)     //scaleX = (double)1.0*finalX/origX
    .add(scaleY);    //scaleY = (double)1.0*finalY/origY
RenderedOp tempProcessingFile = JAI.create("SubsampleAverage", pb, quality);

//Save the file
FileOutputStream fout = new FileOutputStream(file);
JPEGEncodeParam encodeParam = new JPEGEncodeParam();
encodeParam.setQuality(0.92f); //My experience is anything below 0.92f gives bad result
ImageEncoder encoder = ImageCodec.createImageEncoder("JPEG", fout, encodeParam);
encoder.encode(tempProcessingFile.getAsBufferedImage());

, , , .

(The links above are from my bookmark, edit them if you find that they are dead)

+2
source

All Articles