【问题标题】:Displaying image object from controller in the browser在浏览器中显示来自控制器的图像对象
【发布时间】:2013-12-01 22:16:48
【问题描述】:

我在 Java 中使用 playframework 2.2.1,
我正在尝试传递 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))">

我找到了一些关于这个话题的信息(onetwothreefour),
但它通常与旧版本或 Scala 版本的 play 有关。
请提出任何建议或指出我的错误,
谢谢

【问题讨论】:

  • 我不明白你想要达到什么目的。我建议在优化方面遵循 YAGNI 的基本原则:“你不需要它”。如果您不了解自己在做什么,这甚至更有效,因为如果您不了解自己在做什么,您如何对是否值得优化做出明智的判断?

标签: playframework-2.0 playframework-2.1 playframework-2.2


【解决方案1】:

对于字节数组图像,这是我的解决方案(基于 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())}>

【讨论】:

  • 对我来说没用,但我将 ByteArrayInputStream input = null; 更改为 InputStream input = null; 并且它有效。我使用ByteArrayInputStream 得到异常,我在ByteArrayInputStream 的构造函数上得到空指针异常。
【解决方案2】:

虽然可以将图像直接嵌入 HTML 文档,但并非所有浏览器都支持。为此,您需要将图像编码为 Base64。编码后生成的图像将比正常提供时大 33%,并且无法缓存,因此除非图像非常小,否则您将获得比正常提供更差的性能。我以前用它来制作表情符号和其他非常小的图形。我不会用它来做更大的事情。

您可以在此处阅读有关优缺点的更多信息:

Should I embed images as data/base64 in CSS or HTML

要实现这一点,您需要编写一个返回字符串而不是结果的方法,并且该字符串需要看起来像这样:

data:image/jpg;base64,<base64 encoded image here>

【讨论】:

    【解决方案3】:

    您应该在src 属性中使用getImage() 操作而不是其Result 的路由:

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

    顺便说一句:虽然我们不知道您对图像进行了何种处理,但有时将它们保存到光盘中是有意义的——尤其是当它们有可能被重复使用时。在这种情况下,您可以将其退回:

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

    当然仍然使用route 作为src ;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-07
      • 1970-01-01
      • 2021-12-01
      • 2021-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-05
      相关资源
      最近更新 更多