将 byte[] 转换为数据 URI 的 Base64 字符串

Posted

技术标签:

【中文标题】将 byte[] 转换为数据 URI 的 Base64 字符串【英文标题】:Convert byte[] to Base64 string for data URI 【发布时间】:2011-06-17 19:56:14 【问题描述】:

我知道这可能已经被问了 10000 次,但是,我似乎无法找到这个问题的直接答案。

我的数据库中存储了一个代表图像的 LOB;我从数据库中获取该图像,我想通过 html IMG 标记在网页上显示它。这不是我的首选解决方案,但在我找到更好的解决方案之前,这是一个权宜之计。

我正在尝试通过以下方式使用 Apache Commons Codec 将 byte[] 转换为 Base64:

String base64String = Base64.encodeBase64String(my byte[]);

然后,我试图在我的页面上显示我的图像,如下所示:

<img src="data:image/jpg;base64,base64String from above"/>

它显示的是浏览器默认的“我找不到这个图片”,图片。

有人有什么想法吗?

谢谢。

【问题讨论】:

你能贴出完整的代码吗...我需要它作为参考...我也有同样的问题...但是我不知道代码会是怎样...跨度> 【参考方案1】:

我使用了这个并且效果很好(与接受的答案相反,它使用了不推荐用于这种情况的格式):

StringBuilder sb = new StringBuilder();
sb.append("data:image/png;base64,");
sb.append(StringUtils.newStringUtf8(Base64.encodeBase64(imageByteArray, false)));
contourChart = sb.toString();

【讨论】:

这是正确答案,没有UTF8编码,浏览器会让你头疼的。 你使用了哪些进口产品? IIRC,Base64 类是来自 apache commons 的类,虽然我不太确定(并且不再有权访问该项目)。 StringUtils 未定义。 @Hill 它来自 Apache Commons。看看吧,你可能最终会在每个项目中使用它。【参考方案2】:

根据官方文档Base64.encodeBase64URLSafeString(byte[] binaryData)应该是你要找的。​​p>

JPG 的 mime 类型也是 image/jpeg

【讨论】:

PNG example on the Wikipedia article 建议使用 + 和 / 是可以的。 有没有人真正尝试过使用 Base64.encodeBase64URLSafeString() 的输出来查看它是否在浏览器中工作? encodeBase64URLSafeString() 似乎不会生成有效/标准的 base64 编码。要使 base64 编码的字符串符合 URI,您应该对其应用标准 URI 字符转义。我不认为上面的功能是你想要的。 这个答案实际上并没有为我生成正确的字符串。 Hugo 的答案包含使其工作的缺失编码。【参考方案3】:

这是正确的语法。可能是您的 Web 浏览器不支持数据 URI 方案。见Which browsers support data URIs and since which version?

另外,JPEG MIME 类型是image/jpeg

【讨论】:

【参考方案4】:

您可能还需要考虑将图像流式传输到浏览器,而不是在页面本身上对其进行编码。

这是一个通过 servlet 将文件中包含的图像流式传输到浏览器的示例,可以很容易地采用流式传输 BLOB 的内容,而不是文件:

  public void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException
  
    ServletOutputStream sos = resp.getOutputStream();
    try 
      final String someImageName = req.getParameter(someKey);

      // encode the image path and write the resulting path to the response
      File imgFile = new File(someImageName);

      writeResponse(resp, sos, imgFile);
    
    catch (URISyntaxException e) 
      throw new ServletException(e);
    
    finally 
      sos.close();
    
  

  private void writeResponse(HttpServletResponse resp, OutputStream out, File file)
    throws URISyntaxException, FileNotFoundException, IOException
  
    // Get the MIME type of the file
    String mimeType = getServletContext().getMimeType(file.getAbsolutePath());
    if (mimeType == null) 
      log.warn("Could not get MIME type of file: " + file.getAbsolutePath());
      resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
      return;
    

    resp.setContentType(mimeType);
    resp.setContentLength((int)file.length());

    writeToFile(out, file);
  

  private void writeToFile(OutputStream out, File file)
    throws FileNotFoundException, IOException
  
    final int BUF_SIZE = 8192;

    // write the contents of the file to the output stream
    FileInputStream in = new FileInputStream(file);
    try 
      byte[] buf = new byte[BUF_SIZE];
      for (int count = 0; (count = in.read(buf)) >= 0;) 
        out.write(buf, 0, count);
      
    
    finally 
      in.close();
    
  

【讨论】:

我正在使用 Spring Web MVC 并且整个页面正在使用图块等构建......我真的不想经历创建另一个控制器并分别调用每个图像的 PITA,不过谢谢!【参考方案5】:

如果您不想从 servlet 流式传输,则将文件保存到 webroot 中的目录,然后创建指向该位置的 src。这样,Web 服务器就可以完成提供文件的工作。如果您感觉特别聪明,您可以通过 timestamp/inode/crc32 检查现有文件,并且仅在它在 DB 中发生更改时才将其写入,这可以提高性能。这个文件方法也会自动支持 ETag 和 if-modified-since 头文件,以便浏览器可以正确缓存文件。

【讨论】:

以上是关于将 byte[] 转换为数据 URI 的 Base64 字符串的主要内容,如果未能解决你的问题,请参考以下文章

使用 typescript 使用 data-uri 将图像转换为 base64

将图像数据URI(base64)设置为画布背景

base64的byte[]如何转换成图片

IIS7.5 URL 重写:不要将 POST 转换为 GET

将base64转换为图像是给出位图数据

如何将base64位的字节数组转换成图片并显示