views:

513

answers:

4

Hi, I have an open-source app which uploads photos to Facebook. To save bandwidth, the photos are automatically resized before uploading (Facebook imposes a maximum size limit). A few people have complained about the photo quality, and in fact you can see the difference (see this issue for some demo images).

So my question is, what is the "best" way of scaling down images (i.e. photos) in Java without losing quality, or at least, with minimal quality loss / artifacts?

You can see the current code I have here (resize code via this page).

+1  A: 

What rendering hint are you using? Usually bicubic resampling will be the best. In the photos you are linking to they are very jaggy, which makes me think you are using nearest neighbor as your hint.

In the PictureScaler class that you link to, in the paintComponent method, it uses six different means of resizing the image. Have you tried all six to see which gives the best result?

Kip
I would add that it looks like, in the code, that the questioner has a "high-quality" mode that involves resizing the image in several passes. This seems like a bad idea for much the same reason that you would not want to repeatedly compress and uncompress a sound sample; the image quality will actually be worse and not better.
jprete
Hi, actually I haven't tried all six which I probably should. Although I am using bicubic resampling which, as you say, "should" be the best. I'm also not using the "high quality" mode as it doesn't work in that situation, the Java imaging API seems to be prone to deadlocks! Probably something wrong with my code, not sure what though.
Phill Sacre
A: 

Found this code, you might give it a try.

JRL
+2  A: 

I've tried it all - including the tricks here, and all I can say that you're better of using ImageMagick with whatever interface, Javas imaging libraries are just not up to snuff when it comes to this. You need to support so many formats and algorithms to get it right.

disown
I was hoping to avoid an external call but I think you may be right. Java just doesn't seem to have quite got image processing right yet!
Phill Sacre
A: 

After a few frustrating experiments I found the following resize evaluation, and employed the multi-pass approach in my project.

To do that I copied the getScaledInstance() method into my thumbnail generator class, changed my image read approach to use ImageIO (that one returns a BufferedImage) and am now very happy!

I compared the result with a resize done in Photoshop CS3 and the result is very much the same.

Tom