简体   繁体   English

Grails:在gsp中显示创建的图像

[英]Grails: displaying created image in gsp

I'm very new to Grails so there's probably a very simple answer to this question. 我对Grails很新,所以对这个问题可能有一个非常简单的答案。 I'm trying to display a dynamically created image in a gsp. 我正在尝试在gsp中显示动态创建的图像。 The image is NOT stored in a database, it's created on the fly in the controller. 图像不存储在数据库中,它是在控制器中即时创建的。

What I essentially have is one gsp that has a form which takes in a set of user inputs (requestGraph.gsp). 我本质上拥有的是一个gsp,它有一个接受一组用户输入的表单(requestGraph.gsp)。 Upon submitting the form, the parameters are sent to the a displayGraph action in the controller which queries information from a database completely outside of Grails and creates a chart using the JFreeChart library. 提交表单后,参数将被发送到控制器中的displayGraph操作,该操作完全从Grails之外的数据库查询信息,并使用JFreeChart库创建图表。 I would like to display this image within a displayGraph.gsp or something like that. 我想在displayGraph.gsp或类似的东西中显示这个图像。

So basically within requestGraph.gsp I have a snippet similar to: 所以基本上在requestGraph.gsp中我有一个类似的片段:

<g:form action="displayGraph">
    <!-- ... bunch of labels and boxes -->
    <g:submitButton name="displayGraph" value="Display Graph" />
</g:form>

Within the controller I have something like: 在控制器内我有类似的东西:

def requestGraph = {}

def displayGraph = {
    //... code that uses params  to make an image byte array and assigns to var img
    return [image : img]
}

Within displayGraph.gsp: 在displayGraph.gsp中:

<body>
    <h1>Graph Title</h1>
    <!-- ??? How to dislpay image? -->
</body>

I tried piping the image directly to the output stream in the displayGraph action. 我尝试将图像直接传送到displayGraph动作中的输出流。 This works, but then I lose control of all page formatting in displayGraph.gsp. 这有效,但后来我失去了对displayGraph.gsp中所有页面格式的控制。

Most tutorials I've found create a dedicated action to pipe the image to an output steam then call that action using a tag. 我发现的大多数教程都创建了一个专门的操作来将图像传输到输出流,然后使用标记调用该操作。 The problem is that my image isn't stored in a database and I see no way of passing the image byte array (or even the form parameters) to create/render the image. 问题是我的图像没有存储在数据库中,我看不到传递图像字节数组(甚至表单参数)来创建/渲染图像的方法。 Can anybody help me with this? 任何人都可以帮我吗? Thanks. 谢谢。

If you write the bytes to the output stream, you can treat the controller/action as the source of the image in your GSP. 如果将字节写入输出流,则可以将控制器/操作视为GSP中图像的来源。 Here's a quick, untested example: 这是一个快速,未经测试的例子:

// controller action
def displayGraph = {
    def img // byte array
    //...
    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 <img> tag like this: 然后,您可以在<img>标签的src中访问您的图像,如下所示:

<img src="${createLink(controller: 'myController', action: 'displayGraph')}"/>

Update : 更新

After reading your question again, this may or may not work - it looks like you might be displaying the graph as the result of a form submission. 在再次阅读您的问题之后,这可能会或可能不会起作用 - 看起来您可能会将图表显示为表单提交的结果。 This will only work if you're storing the state on the server somewhere (instead of just getting it from the one request where the form is submitted). 只有在某个地方将状态存储在服务器上时(而不是仅从提交表单的一个请求中获取状态),这才有效。 If you do store enough state on the server to generate the graph, then you'd have to provide some additional parameters to your controller to get the correct image, eg src="${g.link(controller: 'myController', action: 'displayGraph', params: ['id': 1234])}" , where id is how you retrieve the graph state. 如果你在服务器上存储足够的状态来生成图形,那么你必须向控制器提供一些额外的参数来获得正确的图像,例如src="${g.link(controller: 'myController', action: 'displayGraph', params: ['id': 1234])}" ,其中id是你检索图形状态的方式。

I believe it's not about Grails but about HTML. 我相信这不是关于Grails而是关于HTML。 You could: 你可以:

  1. Make the dedicated action that pipes image accept certain parameters, and generate the image in that action; 管道图像接受某些参数的专用动作,并在该动作中生成图像;
  2. Embed it base64-encoded into HTML, like here : 嵌入它base64编码成HTML,就像这里

    <img src="data:image/gif;base64,R0lGODlhUAAPAKIAAAsL...etc..." alt="wow" /> <img src =“data:image / gif; base64,R0lGODlhUAAPAKIAAAsL ...... etc ......”alt =“哇”/>

The following code works in Grails 2.x. 以下代码适用于Grails 2.x.

HomeController.groovy HomeController.groovy

class HomeController {

    def index() {
    }


    def viewImage(){
        def file = new File(params.title)
        def img = file.bytes
        response.contentType = 'image/png' // or the appropriate image content type
        response.outputStream << img
        response.outputStream.flush()
    }
}

views/home/index.jsp 意见/家/ index.jsp的

<%@ page contentType="text/html;charset=ISO-8859-1" %>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
    <meta name="layout" content="main"/>
    <title>View Image</title>
</head>
<body>
  <div class="body">
  <img src="<g:createLink controller="home" action="viewImage"
          params="[title: 'C:/pictures/myimage.png']"/>"/>
  </div>
</body>
</html>

Just an improvement to @Rob's answer: 只是对@ Rob的回答有所改进:

Another option which is a bit nicer, you can just render the image, straight from your controller's action: 另一种选择更好一点,您可以直接从控制器的动作渲染图像:

// controller action
def displayGraph = {
    def img // a byte[], File or InputStream
    render(file: img, contentType: 'image/png')
}

See also: http://grails.org/doc/latest/ref/Controllers/render.html 另见: http//grails.org/doc/latest/ref/Controllers/render.html

my suggestion actually has two parts. 我的建议实际上有两个部分。

1) Use the solution recommend by Rob above to generate the chart artifact, however save it to a static file with a unique identifier that is passed back as part of the response from the form submit, then rendering the chart is no different then rendering any other image. 1)使用上面Rob推荐的解决方案来生成图表工件, 但是将其保存到具有唯一标识符的静态文件中,该标识符作为表单提交的响应的一部分传回,然后渲染图表与渲染任何图表没有区别其他形象。

i would suggest that the identifer be constructed from the specifif params passed in on the form submit so they can be used as a caching mechanism to render the chart again without rebuilding it 我建议使用在表单提交中传递的特定参数来构造标识符,以便它们可以用作缓存机制来再次呈现图表而无需重建它

2) create a service, maybe a Quartz Service , that periodically cleans up the static charts that were created for the application 2)创建一个服务,可能是Quartz服务 ,定期清理为应用程序创建的静态图表

我使用FileUploadService在Grails中保存图像文件。如果从目录中获取图像,请尝试以下操作:

<img style="height: 120px;width: 102px;"src="${resource(dir:'personImages', file:    personalDetailsInstance.id + '.png')}" />

Your gsp: 你的gsp:

<img src="${createLink(controller: "image", action: "draw")}" />

Your controller: 你的控制器:

def draw() {
  byte[] imageInBytes = imageService.getImageInBytes() //should return byte array 

  response.with{
    setHeader('Content-length', imageInBytes.length.toString())
    contentType = 'image/jpg' // or the appropriate image content type
    outputStream << imageInBytes
    outputStream.flush()
  }
}

For any reasons the above solutions does not display any image. 由于任何原因,上述解决方案不显示任何图像。 I used: 我用了:

<img src='${createLink(controller: "myController", action: "displayGraph")}' />

instead. 代替。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM