JSP How to scale an image?

user236501 picture user236501 · May 30, 2010 · Viewed 11.6k times · Source

Is there anyway to scale an image then display in jsp page? When retrieve and display the images, I want to show all photos in same size. is there any API can do it? I have searched from google, those I found was about scaling images byusing tookit but can't works in web application.

Answer

BalusC picture BalusC · May 30, 2010

You can use the builtin Java 2D API for this (basic Sun tutorial here).

Basically, you need to create a Servlet which gets an InputStream of the original image in the doGet() method, passes it through the Java 2D API and then writes it to the OutputStream of the HTTP response. Then you just map this Servlet on a certain url-pattern in web.xml, e.g. /thumbs/* and call this Servlet in the src attribute of the HTML <img> element.

Here's a basic kickoff example (you still need to handle unexpected conditions yourself the way you want):

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // First get image file name as request pathinfo (or parameter, whatever you want).
    String imageFilename = request.getPathInfo().substring(1);

    // And get the thumbnail dimensions as request parameters as well.
    int thumbWidth = Integer.parseInt(request.getParameter("w"));
    int thumbHeight = Integer.parseInt(request.getParameter("h"));

    // Then get an InputStream of image from for example local disk file system.
    InputStream imageInput = new FileInputStream(new File("/images", imageFilename));

    // Now scale the image using Java 2D API to the desired thumb size.
    Image image = ImageIO.read(imageInput);
    BufferedImage thumb = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB);
    Graphics2D graphics2D = thumb.createGraphics();
    graphics2D.setBackground(Color.WHITE);
    graphics2D.setPaint(Color.WHITE); 
    graphics2D.fillRect(0, 0, thumbWidth, thumbHeight);
    graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, null);

    // Write the image as JPG to the response along with correct content type.
    response.setContentType("image/jpeg");
    ImageIO.write(thumb, "JPG", response.getOutputStream());
}

With the servlet mapped in web.xml as follows:

<servlet>
    <servlet-name>thumbServlet</servlet-name>
    <servlet-class>com.example.ThumbServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>thumbServlet</servlet-name>
    <url-pattern>/thumbs/*</url-pattern>        
</servlet-mapping>

This can be used as follows:

<img src="thumbs/filename.jpg?w=100&h=100" width="100" height="100">

Note: no, this cannot be done with JSP alone since it's a view technology unsuitable for this task.


Note 2: this is a pretty expensive (CPU intensive) task, keep this in mind. You may want to consider to cache or pregenerate the thumbs beforehand yourself.