Pythonで画像をData URIに変換する

Pythonで画像をData URIに変換する プログラミング

「画像をデータURIスキームに変換したい」
「PythonでファイルをData URIで表現したい」

このような場合には、この記事の内容が参考となります。
この記事では、Pythonで画像をData URIに変換する方法を解説しています。

本記事の内容

  • Data URIとは?
  • Base64によるエンコード
  • MIMEタイプの判定
  • 【サンプルコード】画像からData URIへの変換

それでは、上記に沿って解説していきます。

Data URIとは?

Data URIは、正確にはData URI scheme(データURIスキーム)と言います。
次のようなimgタグを見たことがあるでしょう。

このsrcの値が、Data URI形式のデータとなります。
Data URI形式のデータを初めて見たときは、驚いたことを覚えています。

そして、Data URIには構文が定められています。

data:[<MIME-type>][;charset=<encoding>][;base64],<data>

charsetとはありますが、無視します。
base64形式でエンコードする場合は、charsetは指定する必要がありません。

従って、基本的には次の構文を覚えましょう。

data:[<MIME-type>][;base64],<data>

また、Data URIにはメリット・デメリットが存在しています。
正直、今の時代に速度なんてそれほど気にすることはないと思います。

Data URIの最大のメリットは、画像を実際に作成する必要がないことだと捉えています。
通常は、以下のようにパスに画像を配置しないといけません。

<img src="https://example.com/sample.jpg">

しかし、Data URIでは画像をサーバ上に配置する必要がありません。
これの何が嬉しいのか言うと、サーバの管理面で大いに助かります。

無駄な画像を作らないことで、ディスク容量が節約できます。
そして、無駄な画像を削除するcronを設定する必要もなくなります。

そもそも、画像設置用のディレクトリを設ける必要がありません。
そうなると、書き込み権限を与えて云々も不要になります。
つまり、余計なセキュリティホールを設けなくて済みます。

このように、サーバ管理の面では嬉しいことがあるのです。
PythonでData URIの恩恵を受けるには、以下の点をクリアする必要があります。

  • Base64によるエンコード
  • MIMEタイプの判定

以下では、これらについて説明します。

Base64によるエンコード

Python標準モジュールには、base64が用意されています。
そのため、PythonではBase64によるエンコードがデフォルトで利用可能です。

実際のコードを見た方が理解できるでしょう。
まず、次の画像を用意します。

reddot.png

この画像を読み込んで、Base64でエンコードします。
そのためのコードは、以下。

import base64

file_path = "reddot.png"

with open(file_path, "rb") as image_file:
    data = base64.b64encode(image_file.read())

    # 文字列に変換
    data_str = data.decode('utf-8')
    print(data_str)

上記を実行した結果は、以下となります。

iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==

ここでのポイントは、2つあります。
コード上に出てくる関数が、そのままポイントになります。

  • b64encode
  • decode

それぞれを下記で説明します。

b64encode

渡す値も戻り値もbytes型のデータです。
bytes型の入力値をbytes型のままBase64にエンコードして戻します。

decode

bytes型のデータを指定した文字コードの文字列に変換します。
指定する文字コードは、UTH-8固定で問題はないでしょう。

以上、Base64によるエンコードを説明しました。
次は、MIMEタイプの判定を説明します。

MIMEタイプの判定

MIMEタイプの判定は、ピンからキリまであります。

ピンは、単純にファイル拡張子からMIMEタイプの判定する方法です。
しかし、この方法は拡張子詐欺に騙されてしまいます。

折角ならば、キリの方法でMIMEタイプの判定を行います。
キリの方法なら、拡張子詐欺には騙されません。

その方法を行うには、python-magicをインストールする必要があります。
次の記事を参考にして、python-magicをインストールしてください。

では、MIMEタイプの判定を行います。
コードは、以下を用います。

import magic

file_path = "reddot.png"

with open(file_path, "rb") as image_file:
    # MIMEタイプ取得
    mime_type = magic.from_buffer(image_file.read(), mime=True)
    print(mime_type)

上記を実行した結果は、以下。

image/png

以上、MIMEタイプの判定についての説明でした。
最後に、実際に画像からData URIへの変換を行います。

【サンプルコード】画像からData URIへの変換

画像からData URIへの変換を行うのは、以下のコードとなります。

import base64
import magic

file_path = "reddot.png"

with open(file_path, "rb") as image_file:
    # bufに格納
    buf = image_file.read()

    # base64のdata取得
    data = base64.b64encode(buf)
    data_str = data.decode('utf-8')

    # MIMEタイプ取得
    mime_type = magic.from_buffer(buf, mime=True)

    # Data URI
    data_uri = "data:" + mime_type + ";base64," + data_str
    print(data_uri)

内容的には、説明してきたコードを組み合わせただけです。
少し異なるのは、以下ぐらいでしょうか。

    # bufに格納
    buf = image_file.read()

上記コードを実行した結果は、以下となります。

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==

Data URIの形式通りのデータにはなっています。
でも、モノをみないと信用できません。

確認のために、次のようなhtmlを用意します。

test.html

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==">

このhtmlをブラウザで確認しましょう。

ちゃんと画像として表示されていることが確認できました。

以上、画像からData URIへの変換を説明しました。

タイトルとURLをコピーしました