簡體   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