Resizing images in Java using Java2D

0

Last friday a customer asked us if we knew how to resize
images in java. Their clients are uploading images that need to be resized
automatically. In the past I did some things with Java 2D and knew there was a
lot possible with Java 2D. So I started to look there. After a few minutes I
found the Java2d FAQ with a perfect explanation in it 

And when you read further in the FAQ you’ll also find out
how to create a servlet that outputs an image 

Merging the two FAQ sections and adding some extra things is
all you need to do.....

 
Create a new class called ImageResizeServlet:

 
public class
ImageResizeServlet extends HttpServlet {

    public void doGet(HttpServletRequest
request, HttpServletResponse response) {

    }

}

 

Add the servlet definition in your web.xml:

<servlet>

      <servlet-name>irs</servlet-name>

      <servlet-class>

            nl.amis.ImageResizeServlet

      </servlet-class>

      <load-on-startup>0</load-on-startup>

</servlet>

 

<servlet-mapping>

      <servlet-name>irs</servlet-name>

      <url-pattern>*.jpg</url-pattern>

</servlet-mapping>

Everything in your browser that ends with .jpg will be
redirected to the ImageResizeServlet. Copy the method fom the Java2D FAQ that
resizes the image:

<strong>BufferedImage createResizedCopy(Image originalImage, <o /></strong>
<strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>int scaledWidth, int scaledHeight, <o /></strong>
<strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>boolean preserveAlpha)<o /></strong>
<strong>{<o /></strong>
<strong><span>&nbsp;&nbsp;&nbsp; </span>int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;<o /></strong>
<strong><span>&nbsp;&nbsp;&nbsp; </span>BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);<o /></strong>
<strong><span>&nbsp;&nbsp;&nbsp; </span>Graphics2D g = scaledBI.createGraphics();<o /></strong>
<strong><span>&nbsp;&nbsp;&nbsp; </span>if (preserveAlpha) {<o /></strong>
<strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>g.setComposite(AlphaComposite.Src);<o /></strong>
<strong><span>&nbsp;&nbsp;&nbsp; </span>}<o /></strong>
<strong><span>&nbsp;&nbsp;&nbsp; </span>g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null); <o /></strong>
<strong><span>&nbsp;&nbsp;&nbsp;&nbsp;</span>g.dispose();<o /></strong>
<strong><span>&nbsp;&nbsp;&nbsp; </span>return scaledBI;<o /></strong>
<strong>}<o /></strong>

 

I also added the line g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,                
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
before the
drawImage() to get better resizing quality. The Boolean preserveAlpha is meant
for images with alpha channels (like PNG), but when I set it to false with a JPG
image (which has no alpha channel) I got strange results, so it’s better to use
true here, even if you don’t use an alpha channel.

 
The last step is putting the next piece of code inside the
doGet method:

response.setContentType("image/jpeg");

 

BufferedImage
image = null;

try {

    image = ImageIO.read(new
File("c:\\temp\\307cc.jpg"));

} catch
(IOException ioe) {

    // TODO log error

}

 

int x =
image.getWidth();

int y =
image.getHeight();

 

int new_x =
640;

int new_y =
(new_x * y / x);

 

try {

    // Write image to the output stream

    ServletOutputStream os =
response.getOutputStream();

    ImageIO.write(createResizedCopy(image,
new_x, new_y, true), "jpeg",

            os);

} catch
(IOException e) {

    // TODO log error

}

 

The response type is set to jpeg, other formats are also
available (GIF,  PNG, BMP and WBMP). Now
create a BufferedImage from a file.

The next section with all the ints is needed to preserve the
aspect ratio of the image. We want an image with a width of 640 pixels.

The last step is writing the resized image to the
outputstream (the web browser of the client) with the method from the Java 2D
FAQ.

 
Instead of using a servlet it is also possible to use a
Struts Action or a Spring Controller, as long as you have a HttpResponse object
and return null at the end (instead of an ActionForward or ModelAndView)

 
In the past it wasn’t possible in Linux to create images
from the command line, only when you started your jvm inside an X-enviroment.
Servers usually only have a command line so this is quite a limitation. When I was
testing my example I deployed my application on my Linux server at home (a 6
months old Ubuntu installation) and it worked like I hoped it would! It’s no longer needed to run your jvm in a graphical enviroment, it might perform a little bit worse (because you’re not using the buffer of your video card) but it still performs quite good.

 

Share.

About Author

Comments are closed.