0

I have a barcode that I am dynamically generating, and want to pass to a gsp that will later become a pdf. I do not need to persist the barcode for any of my own purposes, and would like to simply pass the image from the controller to the gsp.

Is there a way to render an image that is passed as a variable rather than specifying a src?

Thanks in advance.

EDIT:

Since I am generating the pdf from the gsp, I am flushing the output stream of the response then, and therefore cannot do it with the image also, or I get an error.

Furthermore, using javascript/jQuery does not work since the page is never rendered directly by the browser.

It may look like the only option I have is to persist the images temporarily somewhere, and then delete them...

Igor
  • 33,276
  • 14
  • 79
  • 112
  • Ach, nevermind, just noticed that IE up to 7 does not support it? – Igor Jan 20 '11 at 21:13
  • I'm not familiar with grails, but the way to do this in PHP is just to set the src attribute to the the script. So, `` and have that PHP script output the raw image data. Could you do something like that? Don't forget to appropriately set your content-type header. – Brad Jan 20 '11 at 21:25
  • That's more of what I was thinking, but we do not use PHP. Would it make sense to render a separate action that would generate and display the image? Or is that overkill? – Igor Jan 20 '11 at 21:28

3 Answers3

2

I answered a similar question recently, perhaps its answer will work for you. I'll paste a portion of it here. It's basically Oded's "outside of this..." suggestion.

class BarcodeController {
    def index = {
        def img // byte array, set this to the binary contents of your image

        response.setHeader('Content-length', img.length)
        response.contentType = 'image/png' // or the appropriate image content type
        response.outputStream << img
        response.outputStream.flush()
    }
}

You could then access your image in the src of an tag like this:

<img src="${g.link(controller: 'barcode', action: 'index')}"/>

This answer seems to fit the last comment you made on the question (about a similar solution using PHP).

Community
  • 1
  • 1
Rob Hruska
  • 118,520
  • 32
  • 167
  • 192
0

Just want to contribute to this age-old question. I got this working by adding the following lines to BuildConfig.groovy:

In the plugins section:

 plugins {
     // other plugins here
     // ...
     compile ":barcode4j:0.3"
     compile ":rendering:1.0.0"
 } 

In the dependencies section:

 dependencies {
     // other dependencies here
     // ...
     compile 'avalon-framework:avalon-framework:4.1.5'
 }

Then I added a controller based on code examples I found on the net. I needed specifically a DataMatrix generator, but adding others should be easy just adding methods to the controller. Sorry for the bad quality code (I'm a Groovy newbie):

package myproject

import org.krysalis.barcode4j.impl.datamatrix.DataMatrix
import java.awt.Dimension

class BarcodeController {

    //  a valid PNG image, base64 encoded  
    static invalidBarcodeImgBase64 = """iVBORw0KGgoAA...=="""

    // Needs index.gsp for testing
    def index() {
        ['uuid': UUID.randomUUID(), 'fecha': new Date()]
    }

    def dataMatrix(String value) {

        if ((null == value) || (value.length() < 1) || (value.length() > 2000)) {
            def img = invalidBarcodeImgBase64.decodeBase64()
            response.setHeader('Content-length', new Integer(img.length).toString())
            response.contentType = 'image/png'
            response.outputStream << img
            response.outputStream.flush()

        } else {
            def generator = new DataMatrix()
            generator.dataMatrixBean.setMinSize(new Dimension(16, 16))
            renderBarcodePng(generator, value, [antiAlias: false])
        }
    }

    def datamatrix(String value) {
        dataMatrix(value)
    }
}

Finally here's index.gsp in the barcode view for testing:

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
  <head>
    <title>DataMatrix</title>
  </head>

  <body>
    <g:img dir="barcode" file="dataMatrix?value=${uuid}"/>
    <br />
    <br />
    <g:img dir="barcode" file="dataMatrix?value=${fecha}"/>
    <br />
    <br />
    <g:img dir="barcode" file="dataMatrix?value=Nothing to see here"/>
  </body>
</html>
dschulz
  • 4,666
  • 1
  • 31
  • 31
0

You can use a data URI scheme for the src attribute.

The data URI scheme is a URI scheme that provides a way to include data in-line in web pages as if they were external resources.

Here is an example from the wikipeida article:

<img src="data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGP
C/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IA
AAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1J
REFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jq
ch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0
vr4MkhoXe0rZigAAAABJRU5ErkJggg==" alt="Red dot" />

Outside of this, if you are using a server side technology, you can stream the image data from a script (with the correct mime-type) and point the src attribute to it.

Here is a related SO question for grails.

Community
  • 1
  • 1
Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • It says it is not IE compliant. Is there a solution that is? – Igor Jan 20 '11 at 21:14
  • @UBM - you mean _compatible_. It's IE that isn't compliant. And for this specific solution (data URI schemes), I don't know of a workaround. – Oded Jan 20 '11 at 21:14
  • It looks like the second link refers to using an image from a database. The image I am using is dynamically created in the controller, and is not/will not be persisted anywhere. – Igor Jan 20 '11 at 21:31
  • @UBM - So? Instead of getting it from the DB, you dynamically create it? I don't know grails, but wouldn't that be similar? – Oded Jan 20 '11 at 21:34
  • Sorry, maybe I'm missing something, but I do not think that will work for me. – Igor Jan 20 '11 at 21:39