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 »

5 Responses to “Resize images with Java - high quality and working solution”

  1. 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

  2. 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

  3. 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

  4. 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 :)

  5. 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?

Trackback URI | Comments RSS

Leave a Reply

« Up and running | JSF PhaseListeners in Action - image rendering, back button, simple security »

  • Calendar

    April 2008
    M T W T F S S
        May »
     123456
    78910111213
    14151617181920
    21222324252627
    282930