Отображение объекта изображения из контроллера в браузере

Я использую playframework 2.2.1 с Java,
я пытаюсь передать BufferedImage или ByteArray или ByteArrayInputStream
для просмотра шаблона, чтобы отобразить его в браузере непосредственно из памяти,
без сохранения в хранилище сервера.
> в моем шаблоне просмотра я запрашиваю изображение:

<img src="@{Application.getImage()}"/>

мой контроллер приложений:

public static Result getImage() throws IOException{  
    BufferedImage image = ImageIO.read(new File("public/img/1.jpg"));  
    //some image manipulations  
    ByteArrayOutputStream baos = new ByteArrayOutputStream();  
    ImageIO.write(image, "jpg", baos);  
    return ok(baos.toByteArray()).as("image/jpg");  
}

в сгенерированном html я получаю:

<img src="SimpleResult(200, Map(Content-Type -&gt; image/jpg))">

Я нашел некоторую информацию по этой теме (one, два, три, четыре),
но обычно это относится к более старым версиям или версиям игры Scala.
Пожалуйста, предложите что-нибудь или укажите на моя ошибка,
Спасибо


person snp0k    schedule 01.12.2013    source источник
comment
Я не понимаю, чего вы хотите добиться. Я предлагаю следовать основному принципу YAGNI: вам это не понадобится, когда дело доходит до оптимизации. И это еще более справедливо, если вы не понимаете, что делаете, потому что, если вы не понимаете, что делаете, как вы можете сделать обоснованное суждение о том, стоит ли оптимизация?   -  person Robin Green    schedule 02.12.2013


Ответы (3)


Вы должны использовать маршрут к действию getImage() вместо его Result в атрибуте src:

<img src='@routes.Application.getImage()'/>

Кстати: Хотя мы не знаем, какие манипуляции вы делаете с изображениями, иногда имеет смысл сохранять их на диск, особенно если есть вероятность, что они будут использованы повторно. В таком случае вы можете вернуть его с помощью:

return ok(new File("/path/to/file"));

Конечно, все еще с использованием route как src ;)

person biesior    schedule 02.12.2013

Для изображений массива байтов здесь мое решение (на основе других решений в stackoverflow):

Контроллер:

public static Result getImage(Long id) {
    Entity entity = Entity.find.byId(id);
    ByteArrayInputStream input = null;

    if (entity.getImage() != null) {
        input = new ByteArrayInputStream(entity.getImage());
    } else {
        try {
            byte[] byteArray;
            File file = Play.getFile("/public/images/no_photo.jpg", Play.current());
            byteArray = IOUtils.toByteArray(new FileInputStream(file));
            input = new ByteArrayInputStream(byteArray);
        } catch (Exception e) {

        }
    }

    return ok(input).as("image/jpeg");
}

Файл маршрутов:

GET     /entity/image/:id       controllers.Entities.getImage(id:Long)

Вид:

<img src=@{routes.Entities.getImage(entity.getId())}>
person Benchik    schedule 30.12.2013
comment
У меня не сработало, но я изменил ByteArrayInputStream input = null; на InputStream input = null;, и это сработало. Я получил исключение, используя ByteArrayInputStream, я получил исключение нулевого указателя в конструкторе ByteArrayInputStream. - person Al-Mothafar; 09.03.2016

Хотя можно вставлять изображения непосредственно в HTML-документы, это поддерживается не всеми браузерами. Для этого вам нужно закодировать изображение как Base64. Результирующее изображение будет на 33% больше после кодирования, чем оно было бы при обычном обслуживании, и не будет кэшироваться, поэтому, если изображение не очень маленькое, вы получите худшую производительность, чем при обычном обслуживании. Я использовал это раньше для смайликов и другой очень маленькой графики. Я бы не стал использовать его для чего-то большего.

Подробнее о плюсах и минусах можно прочитать здесь:

Должен ли я вставлять изображения как data/base64 в CSS или HTML

Чтобы реализовать это, вам нужно написать метод, который возвращает строку, а не результат, и эта строка должна выглядеть примерно так:

data:image/jpg;base64,<base64 encoded image here>
person James Roper    schedule 01.12.2013