April 29th 2008 06:34 pm
Resize images with Java - high quality and working solution
You want simple thing - pure Java utility method that takes image and resize it (to smaller image) to specified dimension with the same quality as Photoshop resized image.
So, here it goes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | import com.sun.image.codec.jpeg.JPEGImageEncoder; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGEncodeParam; import javax.swing.*; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.awt.*; import java.awt.image.BufferedImage; import java.awt.image.Kernel; import java.awt.image.ConvolveOp; public class ImageUtil { public static void resize(File originalFile, File resizedFile, int newWidth, float quality) throws IOException { if (quality < 0 || quality > 1) { throw new IllegalArgumentException("Quality has to be between 0 and 1"); } ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath()); Image i = ii.getImage(); Image resizedImage = null; int iWidth = i.getWidth(null); int iHeight = i.getHeight(null); if (iWidth > iHeight) { resizedImage = i.getScaledInstance(newWidth, (newWidth * iHeight) / iWidth, Image.SCALE_SMOOTH); } else { resizedImage = i.getScaledInstance((newWidth * iWidth) / iHeight, newWidth, Image.SCALE_SMOOTH); } // This code ensures that all the pixels in the image are loaded. Image temp = new ImageIcon(resizedImage).getImage(); // Create the buffered image. BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null), BufferedImage.TYPE_INT_RGB); // Copy image to buffered image. Graphics g = bufferedImage.createGraphics(); // Clear background and paint the image. g.setColor(Color.white); g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null)); g.drawImage(temp, 0, 0, null); g.dispose(); // Soften. float softenFactor = 0.05f; float[] softenArray = {0, softenFactor, 0, softenFactor, 1-(softenFactor*4), softenFactor, 0, softenFactor, 0}; Kernel kernel = new Kernel(3, 3, softenArray); ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); bufferedImage = cOp.filter(bufferedImage, null); // Write the jpeg to a file. FileOutputStream out = new FileOutputStream(resizedFile); // Encodes image as a JPEG data stream JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage); param.setQuality(quality, true); encoder.setJPEGEncodeParam(param); encoder.encode(bufferedImage); } // Example usage public static void main(String[] args) throws IOException { File originalImage = new File("/home/username/images/img.jpg"); resize(originalImage, new File("/home/username/images/img-resized-350-quality-0.7.jpg"), 350, 0.7f); resize(originalImage, new File("/home/username/images/img-resized-350-quality-1.jpg"), 350, 1f); } } |
That’s all, enjoy!
If you enjoyed this post, make sure you subscribe to my RSS feed!
5 Comments »
Fabrizio Giudici on 30 Apr 2008 at 3:35 pm #
getScaledInstance() is evil, don’t use it.
http://weblogs.java.net/blog/chet/archive/2007/04/dont_use_getsca.html
Collin Fagan on 30 Apr 2008 at 4:18 pm #
I also faced this issue when I rewrote the icon demo for the Java tutorials. Chet told me himself that getScaledInstance() should never be encouraged. I wish all of this was packed up into some new API that let you do it in one line.
Icon Demo:
http://java.sun.com/docs/books/tutorial/uiswing/components/icon.html
Full details on getscaledinstance
http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html
Greg Sheremeta on 30 Apr 2008 at 5:27 pm #
I used JAI to do this instead of getScaledInstance(). Great quality, very fast.
Inspiration:
http://www.i-proving.ca/space/Technologies/Java+Advanced+Imaging
John Bäckstrand on 30 Apr 2008 at 9:30 pm #
I did this with JAI, and not with a proper kernel/filter solution but instead scaling in multiple steps. I was actually positively surprised at the resulting quality. The code is still in production
Prasanna on 04 May 2008 at 4:05 pm #
Hi, Do you have any code snippet/ idea to compress the image size, basically the byte size?