Grails: отображение созданного изображения в gsp - PullRequest
13 голосов
/ 21 декабря 2010

Я очень новичок в 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.

В большинстве учебных пособий, которые я нашел, создается специальное действие для передачи изображения на выходной поток, а затем вызывается это действие с помощью тега.Проблема в том, что мое изображение не хранится в базе данных, и я не вижу способа передачи байтового массива изображения (или даже параметров формы) для создания / рендеринга изображения.Кто-нибудь может мне помочь с этим?Спасибо.

Ответы [ 8 ]

11 голосов
/ 21 декабря 2010

Если вы записываете байты в выходной поток, вы можете рассматривать контроллер / действие как источник изображения в вашем 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()
}

После этого вы можете получить доступ к своему изображению в src тега <img> следующим образом:

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

Обновление

После прочтения вашего вопроса это может сработать, а может и не сработать - похоже, вы отображаете график как результат отправки формы. Это будет работать, только если вы где-то сохраняете состояние на сервере (вместо того, чтобы просто получать его из одного запроса, в котором отправлена ​​форма). Если вы сохраняете достаточно состояния на сервере, чтобы сгенерировать график, то вам необходимо предоставить некоторые дополнительные параметры вашему контроллеру для получения правильного изображения, например, src="${g.link(controller: 'myController', action: 'displayGraph', params: ['id': 1234])}", где id - это способ получения состояния графика.

3 голосов
/ 21 декабря 2010

Я думаю, что дело не в Grails, а в HTML. Вы могли бы:

  1. Сделайте выделенное действие, чтобы изображение канала принимало определенные параметры, и сгенерируйте изображение в этом действии;
  2. Вставьте его в кодировке base64 в HTML, например здесь :

    wow

2 голосов
/ 23 июля 2014

Просто улучшение ответа @ 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

2 голосов
/ 31 августа 2012

Следующий код работает в 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()
    }
}

views / home / 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>
2 голосов
/ 22 декабря 2010

мое предложение на самом деле состоит из двух частей.

1) Используйте решение, рекомендованное Робом выше, для создания артефакта диаграммы, , однако сохраните его в статическом файле с уникальным идентификатором , который передается обратно как часть ответа от отправки формы, затем рендеринг диаграммы ничем не отличается от рендеринга любого другого изображения.

я бы предложил создать идентификатор из определенных параметров, переданных в отправку формы, чтобы их можно было использовать в качестве механизма кэширования для повторной визуализации диаграммы без ее перестройки

2) создать службу, возможно Quartz Service , которая периодически очищает статические диаграммы, созданные для приложения

0 голосов
/ 07 марта 2017

Ваш 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()
  }
}
0 голосов
/ 20 декабря 2013

Я использовал FileUploadService для сохранения файла изображения В Grails. Если вы получаете изображения из каталога, попробуйте следующее:

<img style="height: 120px;width: 102px;"src="${resource(dir:'personImages', file:    personalDetailsInstance.id + '.png')}" />
0 голосов
/ 17 января 2011

По каким-либо причинам вышеуказанные решения не отображают ни одного изображения. Я использовал:

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

вместо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...