Grails Cookbook - A collection of tutorials and examples

Grails render images on the fly in GSP

This tutorial will show how to generate PNG images on the fly and display inside a GSP. This can serve as a basis on how to create a more complex behavior. For example, creating report graphs for display in your applications.

Sample Output

This tutorial will show how to generate simple shapes based on input size and color. Squares and circles will be supported.


And the images can be combined for display inside a GSP

Generate Images on the fly


This is the code to generate a square and circle on separate controller actions. The java.awt api is used for programming the logic, which is a very common package for generating graphics.
package asia.grails.test
import javax.imageio.ImageIO
import java.awt.Color
import java.awt.Graphics
import java.awt.image.BufferedImage
class TestImageController {
    def square(int size, String color) {
        BufferedImage buffer = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
        Graphics g = buffer.createGraphics();
        Color gfxColor = new Color(Integer.parseInt(color, 16));
        g.setColor(gfxColor);
        g.fillRect(0,0,size,size);
        response.setContentType("image/png");
        OutputStream os = response.getOutputStream();
        ImageIO.write(buffer, "png", os);
        os.close();
    }
    def circle(int size, String color) {
        BufferedImage buffer = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
        Graphics g = buffer.createGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0,0,size,size);
        Color gfxColor = new Color(Integer.parseInt(color, 16));
        g.setColor(gfxColor);
        g.fillArc(0, 0, size, size, 0, 369);
        response.setContentType("image/png");
        OutputStream os = response.getOutputStream();
        ImageIO.write(buffer, "png", os);
        os.close();
    }
}

For both actions, a BufferedImage is created that will hold the resulting image. The image buffer is manipulated via the Graphics class. The resulting image binary is streamed to the user via the response.outputStream object. The content type should be set so that the browser will be able to understand that the incoming binary is an image.

A square image with 80 pixel sides and cyan color is generated If we access this URL: http://localhost:8080/forum/testImage/square?size=80&color=0ff0ff

A circle image with 150 pixel diameter and blue color is generated If we access this URL: http://localhost:8080/forum/testImage/circle?size=150&color=0000ff

Rendering in GSP

To render the images inside GSP is straightforward. Here is a sample Controller and GSP.

package asia.grails.test
class TestController {
    def index() {}
}

index.gsp
<%@ page import="asia.grails.forum.DiscussionThread" %>
<!DOCTYPE html>
<html>
	<head>
		<meta name="layout" content="main">
		<title>Image Test</title>
	</head>
	<body>
        <g:img dir="testImage" file="square?size=150&color=ff0000"/>
        <g:img dir="testImage" file="square?size=50&color=00ff00"/>
        <g:img dir="testImage" file="square?size=75&color=0000ff"/>
        <g:img dir="testImage" file="circle?size=125&color=00ffff"/>
        <g:img dir="testImage" file="circle?size=25&color=ff00ff"/>
        <g:img dir="testImage" file="circle?size=225&color=ffff00"/>
	</body>
</html>
The dir is mapped to a controller and file maps to the action plus the request parameters.

The result is the image shown below: