rm /blog

IT系技術職のおっさんがIT技術とかライブとか日常とか雑多に語るブログです。* 本ブログに書かれている内容は個人の意見・感想であり、特定の組織に属するものではありません。/All opinions are my own.*

【HTML】IMGタグに画像データ文字列を指定して、直接画像を埋め込む(+JAVAによるBASE64エンコードの方式)

HTMLのIMGタグのSRC属性には、通常外部の(自分自身のHTMLファイルとは別の)画像ファイルを指定するのだが、
画像のデータを示す文字列を指定することで、
外部の画像ファイルを使用せずに自身のHTMLファイル内で「画像」データを再現できる。
※ただしその分、HTMLファイルの容量自体が膨らむ。
特定の静的HTMLコンテンツがそれだけで完結していて、
外部の画像を読み込むような隙がない(配置された場所からしてネットワーク環境的に不可能な)ケースで使用する。
↑のような書き方をするとなんとなくレアケースにしか感じないが、実際、あったのである。(実体験故、詳しいことが書けない)

記述方法は以下の通りだ。

<img src="data:image/png;base64,[BASE64エンコードされた文字列]" alt="base64test">

 


 

 


実例でいうと、例えば

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAARWSURBVHhe7djrcdw6DIZh1+WCXI+rcTMuxqGklxG4vIIiqd0dPL9OCPCCbxTnjD/+TDMLS8HCUrCwFCwsBQtLwcJSsLAULCwFC0vBwlKwsBQsLIVnCeujAa33uecFTH8Zx62y7j7mm4ZrZpp+B6Oswq1zTDyd59+BF4w2/lzeq8HOGro12DnIyON4YAM2XMNZDdhw2biDauibgzvy6LtmwCk8J4+++bgvj75el/cX0bQc16fQ0eXa5gzKd+M1KXQo9W7Lo+M58KYUOjS69mRQfj68L0K5mX5DBuVnxSsjlNsouzMor/Tz9fHx9cMfWvHcELUGmtYUaqHf70/KeZ/fv3RX2jOJdIXlcGqIWs2lsChMUwqkNyyH1wsUapr7IhTm2T448f09uBCWwwwChaK2pgiFmSppbGX0ZcZmgUJeQ0cKtSQxRllpyOqHIxq4MP8VJu17HlHL6AmLgkZ19sD+E7/SHp94ZKaJbJ8mQCGjVo5QUHKDNE/Bh6IO67CtKwLbrwpQSFkTVvME+ze1df7/j5xcWEpMJVBIKdYiFLQas9raRADH/37lAhkUlrNPFqAQUYTFqtYeQTWqTFd+87iwnG08gdXI1LD2Uaszlb+gUoxPExb7BAptjgSaPqhq037YY9fMsBwKodawWH1fzOmxGrKwwJweqyELC8wpUBAyEYZYfXdM67EqWFgnpvVYFSysE9N6rAoW1olpPVYFC+vEtB6rgoV1YlqPVcHCOjGtx6pgYZ2Y1mNVsLBOTOuxKmSDYIfH6vtiToGCYGGBOT1WQxYWmNNjNdQalkPhkp+v7ZdQv9+f9V9iLcaQHquhUgTs81hVcNE8hkJOR2hpN0TJhAKF0Oywokjqad0fFqsRRVgOhRqXRE5DDKvD4mUChUhlfnZ7rDZyU/f8mnzb9qDjlHbc4bGaogvLodCi8xNZ+mUxlUAhpT48ZwgUqs6fS6m/l9mv5c6wWM2YGFbhZ3jRurCYR6CQ0TQ5JwkUSrpnXhQWkwgU8lo/E84TKOSoRnbNnIqpP9EdrglRy+sPy6GWEmRV/gu5/UCTucrkpoTG2SFqRa1hOZwaovbIBfB//so3FpXFwvEPQ2m32v7qR9RqFGE5nB2iJmzfxvlNbH8qzbslIr6gcLNT26/Ai0PUGujCcrghRA3i08DxhTwQiQT1oR+SwPEham3UYTncE6H8fHhfhHKzzgm5LUL5mfCyCGWN/vG4M4WOu/GaFDqULg3GzSl03IRHZNCkN2AqnhChvBZ3Z9DUa8xIvCVEbRVuzaPvgmEj8SKBwkzcVEP3ZbPCYnUCLmjDnkFuC4u+abhmqHvComkO7phgdViU5+COaZaGRW0ojl5iUVisjsCJd5geFn/OoOlFjHwuAXjxinRseS0Twypgw6tZHRatr2ldWDS9skVh0fHipodF7S3MDYvCuxg8DyG9XUyH95xqEgtLwcJSsLAULCwFC0vBwlKwsBQsrGZ/f/8A2blunFhyeAkAAAAASUVORK5CYII=" alt="base64test">


というような感じである。
↑は↓の画像を指している。
base64test
IE7以降が対応しているらしい。



BASE64エンコーディングは、javaのバージョンが1.8以降なら専用のエンコーディング用クラス(java.util.Base64.Encoder)があり、
それを使って手軽にエンコーディングできる。
特定の画像(test.png)をBASE64エンコーディングするやり方は

File img_file = new File("test.png");
FileInputStream fis = new FileInputStream(img_file);
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
long file_size = img_file.length();
boolean readable = false;
do {
	byte[] bytes_wk = new bytes[1];
	fis.read(bytes_wk);
	
	baos.write(bytes_wk,0,bytes_wk.length);
	
	read_size = fis.getChannel().position();
	readable = read_size != file_size;
} while(readable);

String base64encodeing_str = Base64.Encoder.encodeToString(baos.toByteArray());


というような感じ。「base64encodeing_str」にBASE64エンコーディングされた文字列が入る。
※画像ファイルを読み込んでbyte化するところ(FileInputStream#read)はほぼ自前の実装なので、素人臭がすごいかもしれない。
 この実装だと1バイトずつ読み込むから画像が重いと時間がかかるだろうことは予測できる。
 1バイトずつ読み込むのだから終了判定にわざわざFileChannel使う必要もなさそうだし…
 そこも含めてなんとなくもう少しスマートなやり方がありそうなものだ。
 ただ探るのが面倒(この記事の本旨でもない)なのでここまでにしておく。


なお、java.util.Base64の登場バージョン(1.8)はこの記事を書いている2014/9/30時点で結構最新版(2014年3月リリースらしい)なので、
これより昔のバージョンのjavaで動かすような場合(開発上の都合でバージョンアップできない等)は
BASE64エンコーディングに該当するロジックを自作するしかない。
ググるとその辺に転がっているので必要なら調べていただきたい。