Преобразовать byte [] в строку Base64 для URI данных - PullRequest
36 голосов
/ 29 января 2011

Я знаю, что, вероятно, об этом спрашивали 10000 раз, однако я не могу найти прямой ответ на вопрос.

В моей базе данных хранится большой объект, представляющий изображение;Я получаю это изображение из БД и хочу показать его на веб-странице с помощью тега HTML IMG.Это не мое предпочтительное решение, но это временная реализация, пока я не найду лучшего решения.

Я пытаюсь преобразовать байт [] в Base64 с использованием кодека Apache Commons следующим образом:

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

Затем я пытаюсь отобразить свое изображение на своей странице следующим образом:

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

По умолчанию в браузере отображается «Я не могу найти это изображение», изображение

У кого-нибудь есть идеи?

Спасибо.

Ответы [ 5 ]

39 голосов
/ 15 ноября 2013

Я использовал это, и оно работало нормально (вопреки принятому ответу, который использует формат, не рекомендуемый для этого сценария):

StringBuilder sb = new StringBuilder();
sb.append("data:image/png;base64,");
sb.append(StringUtils.newStringUtf8(Base64.encodeBase64(imageByteArray, false)));
contourChart = sb.toString();
12 голосов
/ 29 января 2011

Согласно официальной документации Base64.encodeBase64URLSafeString(byte[] binaryData) должно быть то, что вы ищете.

Также MIME-тип для JPG: image/jpeg.

3 голосов
/ 29 января 2011

Это правильный синтаксис. Возможно, ваш веб-браузер не поддерживает схему URI данных. См. Какие браузеры поддерживают URI данных и с какой версии?

Кроме того, тип JPEG MIME: image/jpeg.

2 голосов
/ 29 января 2011

Вы также можете рассмотреть возможность потоковой передачи изображений в браузер, а не кодировать их на самой странице.

Вот пример потоковой передачи изображения, содержащегося в файле, в браузер через сервлет, который можно легко использовать для потоковой передачи содержимого вашего 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();
    }
  }
1 голос
/ 29 января 2011

Если вы не хотите выполнять потоковую передачу из сервлета, сохраните файл в каталоге в корне сети, а затем создайте src, указывающий на это местоположение.Таким образом, веб-сервер выполняет работу по обслуживанию файла.Если вы чувствуете себя особенно умно, вы можете проверить существующий файл по метке времени / inode / crc32 и записать его, только если он изменился в БД, что может дать вам повышение производительности.Этот метод файла также автоматически поддерживает заголовки ETag и if-Modified-Since, чтобы браузер мог правильно кэшировать файл.

...