web-dev-qa-db-ja.com

データURIのbyte []をBase64文字列に変換します

これはおそらく10000回尋ねられていることを知っていますが、質問に対する直接的な答えを見つけることができないようです。

イメージを表すLOBがデータベースに保存されています。 DBからその画像を取得していますが、HTML IMGタグを介してWebページに表示したいと思います。これは私の好みのソリューションではありませんが、より良いソリューションが見つかるまでは一時的な実装です。

Apache Commons Codecを使用して、次の方法でbyte []をBase64に変換しようとしています。

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

次に、次のようにページに画像を表示しようとしています:

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

ブラウザのデフォルトの「この画像が見つかりません」画像を表示しています。

誰にもアイデアはありますか?

ありがとう。

37
El Guapo

私はこれを使用し、うまくいきました(このシナリオには推奨されない形式を使用する受け入れられた答えとは反対に):

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

公式文書によると Base64.encodeBase64URLSafeString(byte[] binaryData) はあなたが探しているものであるべきです。

また、JPGのMIMEタイプはimage/jpeg

12
Crozin

それが正しい構文です。 WebブラウザがデータURIスキームをサポートしていない可能性があります。 どのブラウザがデータURIをサポートし、どのバージョン以降ですか? を参照してください

また、JPEG MIMEタイプはimage/jpeg

3
Daniel Trebbien

また、ページ自体で画像をエンコードするのではなく、ブラウザに画像をストリーミングすることを検討することもできます。

ファイルに含まれる画像を、サーブレットを介してブラウザにストリーミングする例を次に示します。これは、ファイルではなく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();
    }
  }
2
jhouse

サーブレットからストリーミングしたくない場合は、ファイルをwebrootのディレクトリに保存し、その場所を指すsrcを作成します。そのようにして、Webサーバーはファイルを提供する作業を行います。特に賢いと感じている場合は、timestamp/inode/crc32で既存のファイルをチェックし、DBで変更された場合にのみ書き出すことができます。これにより、パフォーマンスが向上します。また、このファイルメソッドは、ブラウザーがファイルを適切にキャッシュできるように、ETagおよびif-modified-sinceヘッダーを自動的にサポートします。

1
Mark Porter