2016-03-15 101 views
2

我想在我的Vaadin應用程序中顯示由某些API(Canon Hack Hack Development Kit的Java庫)返回的BufferedImage,而不將其保存到文件系統。這是否有可能?這在擺動方面似乎並不麻煩,但迄今爲止我還沒有找到在Vaadin做到的方法。在Vaadin中顯示BufferedImage

回答

1

是的,Vaadin使用com.vaadin.server.StreamResource這是完全可能的。 A StreamResource提供了一些InputStream的數據,並且可以在預期的任何地方使用com.vaadin.server.Resource(即鏈接,圖像,圖標...)。

以下示例方法創建在運行一個BufferedImage一個StreamResource

private StreamResource createStreamResource() { 
    return new StreamResource(new StreamSource() { 
     @Override 
     public InputStream getStream() { 
      String text = "Date: " + DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.MEDIUM).format(new Date()); 

      BufferedImage bi = new BufferedImage(370, 30, 
        BufferedImage.TYPE_3BYTE_BGR); 
      bi.getGraphics().drawChars(text.toCharArray(), 0, 
        text.length(), 10, 20); 

      try { 
       ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
       ImageIO.write(bi, "png", bos); 
       return new ByteArrayInputStream(bos.toByteArray()); 
      } catch (IOException e) { 
       e.printStackTrace(); 
       return null; 
      } 
     } 
    }, "dateImage.png"); 
} 

這可以用一個com.vaadin.ui.Image如下使用:

Image image = new Image("", createStreamResource()); 
layout.addComponent(image); 

參考Vaadin文檔約Stream Resources爲更多信息。

+1

這似乎是從緩衝圖像生成一個PNG文件的好方法 - 但它確實將文件保存在文件系統的某處 - 即使我重新啓動tomcat,此方法返回的圖像也是一樣的。要生成一個新的圖像,我需要在方法結尾處更改「文件名」。 我確定可以將文件名更改爲時間戳字符串,但恐怕我會用「舊」圖像填充文件系統。 – CharlieMcAvish

+0

這是正確的,我的答案中顯示的方法將在每次請求時創建一個新的內存映像,這將回答原始問題。當然,您可以將每個映像放入文件系統的緩存中,並在該文件系統已存在的情況下從該緩存中提供。這會打開與緩存有關的全新問題(緩存驅逐等),因此建議您使用現有的緩存實現。 –

+0

順便提一下,StreamResource構造函數末尾的名字是資源的名字,如果您選擇下載資源,它恰好被用作文件名。在我的代碼示例中,沒有數據將寫入文件系統。 –