通常 HTML に画像を埋め込む場合には、画像ファイルがあって、その画像ファイルを img
タグの src
属性で参照することになります。
<img src="example.png" alt="サンプル画像">
画像ファイルを表示させるには、この方法だけではなく、Data URI スキームと言われる仕様があり、インラインで(テキストで)画像を HTML に埋め込むことも可能です。以下のような感じになり、画像データがBase64のデータとしてテキストで埋め込まれています。(Base64データが長いので割愛しています)
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANIAAADSCAIAAACw+wkVAAALX0lEQVR42u2drXLcWBCFBxgEGBgEDPADBBgE+MEMAgLMDf0IAQZ+BANDP0hAQIChgeGLi6+ffv269evLrO7v7/fbrcetHiLs7Ozu7u7vNkNNufhij+jbnmb4t/W8/Nzj1W86/N+//4dM7shnvNMRQVXV1cxs...==">
今回はこれをどうやるのか、というお話です。
なぜインラインでわざわざ埋め込むの?何がうれしいのか?ですが、HTML の中に画像情報をデータとして埋め込んで1セット(1ファイル)で扱えるので、HTTP のリクエスト数を減らせるメリットがあります。また、プログラムで動的に画像データを生成する場合などには、ファイルに書き出すこと無しにそのまま HTML に埋め込めるのでなかなか便利です。
Data URI スキームとは
Data URI スキームは、インラインで画像を HTML に埋め込む仕様で、RFC 2397 で定義されている標準仕様です。
ja.wikipedia.org tools.ietf.org
現在ではほとんどのブラウザで対応されています。
IE、Edge にちょっと制限があります。上記サイトに詳細はありますが、ざっくりとは以下の通りです。
- 容量制限。IE8 は最大 32KB まで。それ以外は、最大 4GB まで。
img
タグに Base64 データで埋め込む書式は以下のような感じで定義されています。
data:[<mediatype>][;base64],<data>
<data>
部に画像データを Base64 に変換したデータを埋め込みます。
Go で画像データを Base64 のテキストデータに
画像データの Base64 データへの変換ですが、どのようにやるのでしょうか。画像データをアップロードすれば Base64 データを作成してくれる Web のサービスなどもありますが、ここでは、実装してみます。
- 画像は ショッピングカートのかわいい手書き風イラストアイコン | 可愛い絵文字アイコンイラスト『落書きアイコン』 からお借りしています。(
1adeddb3a3462f52a576abddb359e55e.png
) - 画像ファイルを読み込み、バイト配列にして、Base64 にエンコードしてテキストで出力、をしているのが以下のソースの概要です。
package main import ( "encoding/base64" "fmt" "log" "os" ) func main() { var err error file, err := os.Open("1adeddb3a3462f52a576abddb359e55e.png") if err != nil { log.Fatal(err) } defer file.Close() fi, _ := file.Stat() size := fi.Size() data := make([]byte, size) if _, err = file.Read(data); err != nil { log.Fatal(err) } fmt.Println(base64.StdEncoding.EncodeToString(data)) }
上記を実行すると標準出力に画像ファイル(1adeddb3a3462f52a576abddb359e55e.png
)の Base64 データが出力されます。
出力された Base64 データを Data URI スキームの書式に倣って HTML に貼り付けます。
正しく表示されているようです。
Base64 自体が冗長なデータフォーマットですので、実際の画像データよりサイズが大きくなってしまうというデメリットもありますが、使いどころはありそうです。
Java で画像データを Base64 のテキストデータに
Java (1.8)でもやってみましたので、メモしておきます。
package com.example.sample; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.util.Base64; public class Main { public static void main(String[] args) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try { BufferedImage image = ImageIO.read(new File("1adeddb3a3462f52a576abddb359e55e.png")); ImageIO.write(image, "png", outputStream); } catch (IOException e) { e.printStackTrace(); System.exit(1); } String base64EncodedImageString = Base64.getEncoder().encodeToString(outputStream.toByteArray()); System.out.println(base64EncodedImageString); } }