java 1.4 good quality image resize
We have a photo gallery that is using servlets to resize images - we need good performance and decent quality, but we just can't get it right. Also, sadly enough, we have only java 1.4, which leaves us to almost no external image libraries (nearly everything i found is java 1.5+) and java image handling is really not good.
If I use this:
private static BufferedImage scaleImage(BufferedImage orig, int type, int w, int h) {
BufferedImage tmp = new BufferedImage(w, h, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(orig, 0, 0, w, h, null);
g2.dispose();
return tmp;
}
the results are almost same every time (and bad looking) or extremely slow, it depends on the selected hint. I read almost every article about image resizing in java (including this o开发者_开发知识库ne and it does not help.
Do you have any ideas? Any external libraries for java 1.4 that are fast and have decent quality? Any algorithm that would get good results?
You might try Image Magick wrappers like JMagick.
Izk, given your requirements I would agree with Thomas and you (likely) need to rely on an external/native library.
If you hadn't explicitly mentioned performance, I would have suggested using BICUBIC interpolation along with Chris Campbell's incremental-scaling algorithm. The imgscalr library implements all of this, but it does require Java 5 (uses Enums). That being said, you can easily copy the code into a Java 1.4-compliant implementation.
Go take a look at the Scalr class, scroll to the VERY bottom, and copy the last two methods. That is all you should need to get you 95% done IF you want to keep it implemented in Java.
But, if you found Java-scaling performance unacceptable up until this point, that implementation won't help you. You'll need to look at using a native library like ImageMagick.
Fortunately ImageMagick has 2 popular Java bindings and if the JMagick API doesn't let you deal with InputStreams, you might look at im4java which is a straight wrapper to the command line version of ImageMagick. I dug through the source code and it looks like the core ImageCommand class used to wrap "commands" to send to the command line util allow you to pass BufferedImage instances as the "images" Object param when executing an operation.
If that is the case you can use ImageIO.read(InputStream) to read the image data into a BufferedImage before sending it off to ImageMagick for processing using the im4java API.
There are a few suggestions to get you where you need to go, I hope they helped.
精彩评论