[Hugo] 画像をbase64に変換してhtml内に埋め込んでみた

アイキャッチ画像


記事内に商品のプロモーションを含む場合があります。

Nプログラマ(@Nprog128)です。

html内に画像を直接埋め込みたい、、、ということがたまぁ〜にあります。

なプ

諸事情は様々ですが、一応こういうのもあるってことで。。。

やり方は、base64に変換した画像の文字列をhtmlに埋め込みます。

なプ

jsやcssをインラインで書くようなイメージです。

で、それを今回はHugoのbase64Encodeという関数を使って埋め込んでみました。

> base64 | Hugo

なプ

ちなみにbase64に変換すると、サイズ量が3割ほど増えます。。。

準備

画像

使用する画像はこんな感じの01.pngというファイルを用意しました。

/img/article/2020/12/16/01.png
サンプル画像
なプ

jpgでもbmpでも、この辺はお好みで。

画像はhugoプロジェクトのstaticディレクトリ配下に置きました。

1> tree static 
2static
3└── img
4    └── 01.png

記述方法

htmlの記述方法は、通常の画像を表示するのは同じでimgタグを使います。

ちょっと違うのはsrc属性の部分で、ここにはdataURLの形式が記述できるので、そこにbase64でエンコードした画像データを記述していきます。

> 参考: データ URL | MDN

大まかにはこんな感じに書きます。

大まかなコード コードを開く
大まかなコード
1<img src="data:image/png;base64,エンコードした文字列">

今回はpng画像を使うのでimage/pngを指定しました。

他の画像形式を使う場合は、jpgならimage/jpg、gifならimage/gifという風に指定をします。

ショートコード

今回はmarkdownで記述するので、base64に変換する専用のショートコード(sample.html)を作成します。

配置する場所は、hugoプロジェクトのlayouts/shortcodes配下に置きます。

1> tree layouts 
2layouts
3└── shortcodes
4    └── sample.html

ショートコードを使わずにmarkdownにhtmlを直書きしたいところですが、Hugoの関数がmarkdown内では直接呼べないのでショートコードを挟みます。

ポイントは、指定した画像パスをreadFileで開く部分です。

なプ

自分は最初、画像パス自体をエンコードしていて、それに気が付かずしばらく表示されない問題で頭を悩ませました orz

readFileはHugoプロジェクト直下からのパスであることにも注意です。

なプ

画像を配置した例でいくと、/static/img/01.pngですねっ!

ショートコード コードを開く
ショートコード
1{{ $file := readFile (.Get `path`) }}
2{{ $media_type := .Get `media_type` }}
3
4<div>
5  <img src="data:image/{{ $media_type }};base64,{{ base64Encode $file }}"/>
6</div>

作成した記事のファイル(markdown)からは、以下のように呼び出します。

1{{< sample path="/static/img/01.png" media_type="png" >}}

これで準備は整ったので、記事内からbase64に変換した画像を表示してみましょう。

画像を表示してみる

下準備したものを使って、実際に画像を表示してみましょう。

画像パス指定の方法

まずはいつも使っている画像パスを指定した画像の表示を見てみます。

コード

1<img src="/img/article/2020/12/16/01.png">

結果

base64に変換した画像を表示

なプ

こちらが本題ですねっ!

それでは、base64に変換した画像をhtmlで埋め込んで表示してみましょう。

先程準備で作ったショートコードを呼び出してみます。

コード

1{{< sample path="/static/img/01.png" media_type="png" >}}

結果

表示結果はこのようになります。

見た目はまったく同じですね!

違いはデータ量がこちらのほうがちょっぴり増えています。

あとはhtml内に画像が埋め込まれているので、読み込まれるファイル数も減ります(その代わりhtmlファイルが増大します)

なプ

この記事では両方検証しているので、ファイル数は増えていますけどね。

ついでにhtmlのコードはどうなっているか確認しておきましょう。

今回はChromeを使っているので、developer toolsを使います。

目的の要素のhtmlを確認してみると、、、

/img/article/2020/12/16/02.png
base64の画像表示

パッと見では何のデータか分からない(basa64で変換したデータ)の文字が並んでいることが確認できました。

編集しようとすると、文字が多すぎるのでvalue is too large to editと、表示されてしまいますね(汗)

これで画像をbase64に変換してhtml内に埋め込むことができました。

オマケ: base64に変換後のサイズ容量の確認

まずは変換前の画像(01.png)のサイズを確認します。

1> wc -c < 01.png                                                                                                                       (git)-[master]
2   16636
なプ

16,636 byte(約17kB)ですね。

次に、base64に変換後のサイズを見てみます。

1> wc -c < encode_base64.txt                                                                                                            (git)-[master]
2   22184
なプ

22,184 byte(約22kB)になり、ちょっと増えていますね。

ざっくりと計算すると、、、

23 [kB] / 17 [kB] = 1.35…

になります。

パーセントで表すと、135%ですね。

なので元の画像よりも135%分サイズが増えているので、冒頭の通りbase64に変換すると約3割ほど増えています。

なプ

しっかり計算すると133%になるので、3割くらいでいいと思います。

おわりに

今回は、Hugoで画像をbase64に変換してhtml内に埋め込んでみた、という内容でした。

利用するケースはあまりないかもしれないですが、こういうこともできると覚えておくといざという時に役立つ、、、

かもしれません、、、(小声)

ちなみに予めbase64に変換したファイルを準備しておけば、Hugoのdecode64Decode関数で表示することも可能です。

画像表示はセキュリティの問題になることもあるので、外部リソースを埋め込んで表示する時は注意したいトコロです。

なプ

今回のようにhugoを使って自身のコンテンツを変換するなら、ほぼ問題ないとは思いますが。

それでは、このへんで。
バイナリー!

\ ちょっとお買い物 /


関連した記事