「画像をデータ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への変換を説明しました。