繁体   English   中英

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

[英]Grails: displaying created image in gsp

我对Grails很新,所以对这个问题可能有一个非常简单的答案。 我正在尝试在gsp中显示动态创建的图像。 图像不存储在数据库中,它是在控制器中即时创建的。

我本质上拥有的是一个gsp,它有一个接受一组用户输入的表单(requestGraph.gsp)。 提交表单后,参数将被发送到控制器中的displayGraph操作,该操作完全从Grails之外的数据库查询信息,并使用JFreeChart库创建图表。 我想在displayGraph.gsp或类似的东西中显示这个图像。

所以基本上在requestGraph.gsp中我有一个类似的片段:

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

在控制器内我有类似的东西:

def requestGraph = {}

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

在displayGraph.gsp中:

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

我尝试将图像直接传送到displayGraph动作中的输出流。 这有效,但后来我失去了对displayGraph.gsp中所有页面格式的控制。

我发现的大多数教程都创建了一个专门的操作来将图像传输到输出流,然后使用标记调用该操作。 问题是我的图像没有存储在数据库中,我看不到传递图像字节数组(甚至表单参数)来创建/渲染图像的方法。 任何人都可以帮我吗? 谢谢。

如果将字节写入输出流,则可以将控制器/操作视为GSP中图像的来源。 这是一个快速,未经测试的例子:

// 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()
}

然后,您可以在<img>标签的src中访问您的图像,如下所示:

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

更新

在再次阅读您的问题之后,这可能会或可能不会起作用 - 看起来您可能会将图表显示为表单提交的结果。 只有在某个地方将状态存储在服务器上时(而不是仅从提交表单的一个请求中获取状态),这才有效。 如果你在服务器上存储足够的状态来生成图形,那么你必须向控制器提供一些额外的参数来获得正确的图像,例如src="${g.link(controller: 'myController', action: 'displayGraph', params: ['id': 1234])}" ,其中id是你检索图形状态的方式。

我相信这不是关于Grails而是关于HTML。 你可以:

  1. 管道图像接受某些参数的专用动作,并在该动作中生成图像;
  2. 嵌入它base64编码成HTML,就像这里

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

以下代码适用于Grails 2.x.

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()
    }
}

意见/家/ 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>

只是对@ Rob的回答有所改进:

另一种选择更好一点,您可以直接从控制器的动作渲染图像:

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

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

我的建议实际上有两个部分。

1)使用上面Rob推荐的解决方案来生成图表工件, 但是将其保存到具有唯一标识符的静态文件中,该标识符作为表单提交的响应的一部分传回,然后渲染图表与渲染任何图表没有区别其他形象。

我建议使用在表单提交中传递的特定参数来构造标识符,以便它们可以用作缓存机制来再次呈现图表而无需重建它

2)创建一个服务,可能是Quartz服务 ,定期清理为应用程序创建的静态图表

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

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

你的gsp:

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

你的控制器:

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()
  }
}

由于任何原因,上述解决方案不显示任何图像。 我用了:

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

代替。

暂无
暂无

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

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