PNGなどの画像ファイルには「メタデータ」と呼ばれる付加情報がついていることがあります。
たとえば、NovelAIやStable Diffusionなどの画像生成AIサービスで生成した画像ファイルには、「どのような設定で画像を生成したのか」という情報が付けられています。
このような情報を確認できれば、気に入った画像を生成できたときのプロンプトや設定情報を参考にできるのでとても便利です。
「メタデータ」がどのようなものかを理解することで、活用の幅が広がります。
本記事ではPNGファイルのメタデータがどのような構造になっているのかを初心者でもわかるように丁寧に解説します。
後半では、実際にPNGファイルからメタデータを抜き出すPythonコードも解説していますので、アプリやツールを作ろうとしている人にも役立つと思います。
メタデータとは
まずはざっくりと「メタデータ」とはどのようなものかを知りましょう。
データを説明するデータが「メタデータ」
早口言葉みたいでよくわからん…どういうこと?
画像ファイルにおいて、メインとなるデータはもちろん「画像データ」です。
ですが、よく考えてみると「画像データ」は画像それ自体の他にもさまざまな情報を持っているはずです。
たとえば、あなたが旅行に出かけて、美味しそうな料理の写真を取ったとしましょう。
そのとき記録に残したい情報は「料理の画像」以外にもいろいろあるはずです。
撮影した日時とか場所とかね💡
カメラの機種や設定も残せたら便利ですよね♪
こうしたさまざまな情報は「画像データ」を説明するデータといえます。これが「メタデータ」なのです。
画像生成AIとメタデータ
Stable DiffusionやNovelAIなどの画像生成AIでは、画像を生成するときにさまざまな設定を駆使しています。プロンプトを工夫したり、ステップ数を調整したり、試行錯誤しながら良い画像を生み出します。
これらの情報が画像ファイルに付けられていたら、あとから見返すことができるのでととても便利ですよね。
これを実現する仕組みが「メタデータ」なのです。
実際にNovelAIではダウンロードした生成画像にはこのようなメタデータが付与されています。
「プロンプト」や「ステップ」「スケール」など多くの情報が付いてます
メタデータの確認方法
Windowsであればファイルを右クリックして「プロパティ」を開くと、いくつかのメタデータを見ることができます。たとえば、画像の幅や高さなどの情報です。ですが、すべての情報がここで確認できるわけではありません。
すべてのメタデータを確認するためには、基本的には専用のツールが必要になります。
Stable DiffusionやNovelAIにはメタデータを確認する機能が備わっているので、それらを使って確認することができます。
Stable Diffusion(WebUI)での確認方法
Stable Diffusion Web UI(AUTOMATIC1111)では、「PNG Info」タブで画像を読み込ませることでメタデータを確認できます。
NovelAIでの確認方法
NovelAIの画像ファイル確認ページに画像を読み込ませることで、メタデータを確認することができます。
ここまでがメタデータの概要です。
さらに詳しくメタデータについて知りたい人は次に進みましょう♪
PNGのメタデータ
では、ここから先はもう少し突っ込んで「メタデータ」について理解していきましょう。
ここまで単に「画像ファイル」と言ってきましたが、「画像ファイル」にもさまざまな形式があります。代表的なものは「PNG(ピング)ファイル」と「JPEG(ジェイペグ)ファイル」です。
ファイルの拡張子が「.png」がPNGファイル、「.jpg」や「.jpeg」となっているのがJPEGファイルです
本記事では「PNGファイル」のメタデータについて解説していきたいと思います。
PNGファイルの大まかな構造
PNGファイルは「シグネチャ」と複数の「チャンク」で構成されています。
「シグネチャ」は「これはPNGファイルだよ」ということを識別するための貼り紙のようなものです。
そして「チャンク」はひとかたまりのデータのことです。さまざまなデータが格納されている「箱」をイメージするといいでしょう。PNGファイルという大きな箱に「チャンク」という小さな箱が詰まっているようなものと考えてください。
「シグネチャ」と「チャンク」
では、具体的に「シグネチャ」と「チャンク」の中身を見ていきましょう。
シグネチャ
「シグネチャ」は「PNGファイル」であることの目印のようなもので、ファイルの先頭に存在しています。
実際のデータは「8byte」で、16進数で表すと「89 50 4e 47 0d 0a 1a 0a」というデータです。
このデータが付いてたらPNGファイルってことね💡
チャンク
「チャンク」は、その中身のデータによっていくつかの種類があり、これを「チャンクタイプ」といいます。チャンクタイプはアルファベット4文字で表現されます。
PNGファイルに必須のチャンクタイプはIHDR、IDATA、IENDの3つです。
IHDRは必ず先頭にあって、IENDは必ず末尾にあります。IDATというのは画像のデータです。
つまり、PNGファイルの全体的な構造は以下のようになります。
ふーん…で、メタデータはどこにあるの?
メタデータもチャンクとして付与されています。PNGファイルに「tEXt」や「iTXt」というチャンクタイプがあれば、それがメタデータです。
「チャンク」の構造
PNGでは「チャンク」が重要な役割を果たしているので、その構造を理解することがとても大切です。
「チャンク」の中身を詳しく見てみましょう。
どのようなチャンクでも必ずこのような構成になっています。
名前 | サイズ | 説明 |
---|---|---|
Length | 4byte | Chank Dataのサイズ |
Chank Type | 4byte | チャンクの種類 |
Chank Data | 0byte以上 | データ本体 |
CRC | 4byte | エラー検出のための情報 |
ポイントは「チャンクデータ」のサイズが可変なこと
チャンクに格納されているデータのサイズはチャンクによって変わります。よって、あらかじめ何byte分のデータを読み出せばいいかがわからないといけません。
そのために「Length」に「このチャンクのデータサイズは何byteだよ」という情報が格納されているわけです。
主なチャンクタイプ
IHDRチャンク
一番始めに来るチャンク。ここからチャンクが始まるよという目印になります。
Chunk Data部分には、画像の横幅や縦幅、ビット深度といった画像の基本情報が格納されています。
IENDチャンク
末尾に来るチャンク。ここでチャンクはおしまいという目印。ただの目印のチャンクなので、Chunk Dataには何も入っていません。
IDATチャンク
画像データが格納されているチャンクです。画像データは複数のIDATチャンクに分割されていることもあります。
tEXtチャンク
メタデータが文字情報として格納されています。
Stable DiffusionやNovelAIの生成画像では、このtEXtチャンクにプロンプトなどの各種情報が入っています。
Chunk Dataはテキストデータなので基本的にはそのまま読み出せばいいのですが、ポイントはこのテキストデータは情報の種類を示す「キーワード」から始まることです。
そしてその後、「ヌル文字」で区切られて「テキスト」が続きます。
キーワードには以下のものが事前定義されていますが、ここにないプライベートキーワード(1文字以上、80文字未満)を用いてもよいことになっています。
キーワード | 意味 |
---|---|
Title | 画像の短い(1 行)タイトルまたはキャプション |
Author | 画像の作成者の名前 |
Description | 画像の説明 (長い場合もあります) |
Copyright | 著作権表示 |
Creation Time | 元画像の作成時間 |
Software | イメージの作成に使用したソフトウェア |
Disclaimer | 法的免責事項 |
Warning | コンテンツの性質に関する警告 |
Source | イメージの作成に使用されたソースデバイス |
Comment | その他のコメント |
PNGのメタデータをPythonで抜き出す
ここからはプログラミングを行ってPNGファイルからメタデータを抜き出すことで、さらに理解を深めます。
画像ファイルは、NovelAIという画像生成AIサービスで生成した以下のpngファイルを使います。実際にダウンロードして使っていただいて構いません。
プログラミング言語としては「Python」を使います。
最初に全コードを載せておきます。
with open("kimono-girl.png", "rb") as bin:
# 最初の8バイトはPNGであることのシグネチャ(89 50 4E 47 0D 0A 1A 0A)
signature = bin.read(8)
print(signature)
# チャンクの読み出し
while True:
# Length データのサイズ
data_len_b = bin.read(4)
data_len = int.from_bytes(data_len_b, "big")
# Chunk Type チャンクの種類
chunk_type_b = bin.read(4)
chunk_type = chunk_type_b.decode()
print(f"{chunk_type} : {data_len} byte")
# Chunk Data データ
data_b = bin.read(data_len)
if chunk_type == "tEXt":
data = data_b.decode()
print(data)
print(data.split("\0"))
# CRC
crc_b = bin.read(4)
if chunk_type == "IEND":
break
順番に解説していきますね♪
with open("kimono-girl.png", "rb") as bin:
まず、pngファイルをバイナリ形式で開きます。open()の第一引数には画像ファイルのパスを指定してください。
画像ファイルは人間が見てもよくわからない数字の列が並んで構成されていますが、この並びには意味があります。
つまり、前から順番にここがシグネチャで、ここがチャンクで…というように並んでいます。
そのためバイナリ形式でファイルを開いて、前から順番にデータを読み出して解釈していきます。
signature = bin.read(8)
print(signature)
bin.read(n)で読み込み位置を進めながら次のnバイトを読み出すことができます。
PNGファイルは、最初の8バイトが「シグネチャ」なので、まずは最初の8バイトを読み込んでいます。
読み込んだファイルがPNGファイルかどうかをチェックしたい場合はこのシグネチャをチェックすればよいです。(このコードでは、特にチェックしていません)
while True:
さて、ここからファイルの終わりまでは「チャンク」が繰り返し続きます。なのでwhile文でループさせます。
# Length データのサイズ
data_len_b = bin.read(4)
data_len = int.from_bytes(data_len_b, "big")
# Chunk Type チャンクの種類
chunk_type_b = bin.read(4)
chunk_type = chunk_type_b.decode()
print(f"{chunk_type} : {data_len} byte")
チャンクの構造を思い出してください。
まず、4ビットのLength、4ビットのChunk Typeが並んでいます。
ポイントはその後に何ビットのデータが続くかはこの「Length」から判断できるということです。
次にデータ本体を読み出します。
# Chunk Data データ
data_b = bin.read(data_len)
if chunk_type == "tEXt":
data = data_b.decode()
print(data)
チャンクの種類によって処理する内容は変わるのですが、「tEXt」(テキストデータ)だったらprint文で出力させてみましょう。
なんか途中に変な文字があるよ…
キーワードとテキストの「区切り文字(ヌル文字)」です
キーワードとテキストはヌル文字で区切られていて、キーワードやテキスト文字列内にはヌル文字を含めてはならないことになっています。したがって、ヌル文字できれいに分割することができます。
print(data.split("\0"))
最後は、CRC(4バイト)を取り出します。これについては特にやることはありません。
# CRC チェックサム
crc_b = bin.read(4)
これでひとつのチャンクの読み込みは完了ですが、次のチャンクに行く前に大切なことがあります。
最後のチャンクかどうかをチェックすることです。
最後ならwhileループを終了させなければいけませんね。
最後のチャンクかどうかはどう判断すればいいでしょう?
えーと…最後は必ず「IEND」チャンクだったよね💡
そうです。チャンクはIENDチャンクが末尾になる決まりでしたね。
よって、チャンクタイプがIENDかどうかをチェックすればOKです。
if chunk_type == "IEND":
break
まとめ
PNGファイルには、その画像を説明するデータである「メタデータ」が付与されていることがあります。
画像生成AIの生成画像では「プロンプト」や「ステップ」「シード値」などの情報を付与できるため、のちのちの画像生成で役立てることもできます。
PNGファイルは「シグネチャ」と複数の「チャンク」という比較的シンプルな構造をしています。
「チャンク」の仕様さえ理解してしまえば、Pythonなどのプログラムでメタデータを抜き出すことは難しくはありません。
実際にプログラミングしたらよく理解できたよ✨
便利なツール作成にもぜひチャレンジしてみてくださいね♪
NovelAIの生成画像のメタデータについてさらに詳しく知りたい人はこちらもぜひどうぞ!
コメント