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:
Reference: | Grails render images on the fly in GSP from our JCG partner Jonathan Tan at the Grails cookbook blog. |