简体   繁体   English

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

[英]Convert byte[] to Base64 string for data URI

I know this has probably been asked 10000 times, however, I can't seem to find a straight answer to the question. 我知道这可能已被问过10000次,但是,我似乎无法找到问题的直接答案。

I have a LOB stored in my db that represents an image; 我有一个存储在我的数据库中的LOB代表一个图像; I am getting that image from the DB and I would like to show it on a web page via the HTML IMG tag. 我从数据库中获取该图像,我想通过HTML IMG标记在网页上显示它。 This isn't my preferred solution, but it's a stop-gap implementation until I can find a better solution. 这不是我的首选解决方案,但它是一个临时实施,直到我找到更好的解决方案。

I'm trying to convert the byte[] to Base64 using the Apache Commons Codec in the following way: 我正在尝试使用Apache Commons Codec以下列方式将byte []转换为Base64:

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

Then, I am trying to show my image on my page like this: 然后,我试图在我的页面上显示我的图像,如下所示:

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

It's displaying the browser's default "I cannot find this image", image. 它显示浏览器的默认“我找不到这个图像”,图像。

Does anyone have any ideas? 有没有人有任何想法?

Thanks. 谢谢。

I used this and it worked fine (contrary to the accepted answer, which uses a format not recommended for this scenario): 我使用它并且它工作正常(与接受的答案相反,它使用的格式不建议用于此场景):

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

According to the official documentation Base64.encodeBase64URLSafeString(byte[] binaryData) should be what you're looking for. 根据官方文档Base64.encodeBase64URLSafeString(byte[] binaryData)应该是你正在寻找的。

Also mime type for JPG is image/jpeg . JPG的mime类型也是image/jpeg

That's the correct syntax. 这是正确的语法。 It might be that your web browser does not support the data URI scheme. 可能是您的Web浏览器不支持数据URI方案。 See Which browsers support data URIs and since which version? 请参阅哪些浏览器支持数据URI以及哪个版本支持?

Also, the JPEG MIME type is image/jpeg . 此外,JPEG MIME类型是image/jpeg

You may also want to consider streaming the images out to the browser rather than encoding them on the page itself. 您可能还想考虑将图像流式传输到浏览器,而不是在页面本身上对它们进行编码。

Here's an example of streaming an image contained in a file out to the browser via a servlet, which could easily be adopted to stream the contents of your BLOB, rather than a file: 这是一个通过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();
    }
  }

If you don't want to stream from a servlet, then save the file to a directory in the webroot and then create the src pointing to that location. 如果您不想从servlet流,则将文件保存到webroot中的目录,然后创建指向该位置的src。 That way the web server does the work of serving the file. 这样Web服务器就可以完成提供文件的工作。 If you are feeling particularly clever, you can check for an existing file by timestamp/inode/crc32 and only write it out if it has changed in the DB which can give you a performance boost. 如果您感觉特别聪明,可以通过timestamp / inode / crc32检查现有文件,只有在DB中发生更改才能将其写出来,这样可以提高性能。 This file method also will automatically support ETag and if-modified-since headers so that the browser can cache the file properly. 此文件方法还将自动支持ETag和if-modified-since标头,以便浏览器可以正确缓存文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM