Groovy

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

zzyy03

And the images can be combined for display inside a GSP:

zzyy01

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

zzyy03

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

zzyy02

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:

zzyy01

Reference: Grails render images on the fly in GSP from our JCG partner Jonathan Tan at the Grails cookbook blog.

Jonathan Tan

Jon is a professional software engineer currently working in financial trading systems. He has worked in a wide variety of projects that includes mobile games, 3D visualization, artificial intelligence, banking and trading systems. He loves to teach people and expresses his passion through blogging.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button