AIで生成した大量の画像をどうやって保存しようか、悩んでいる人も多いと思います。
通常、画像を保存する際に気にするポイントは画質です。しかしそれに加えて、AI生成した画像の保存でネックになるのが「メタデータにプロンプトを残したい」という点です。
1.おさらい
ComfyUIでデフォルト対応している保存形式はPNG、JPEG、WEBPの三種類です。A1111WebUIや他の派生システムも似たようなものだと思います。まあ拡張機能で画像の保存形式は如何様にもなりますが、とりあえず主流の三つで話を進めます。
劣化しないPNGは1枚の容量が大きい(例えば 768x1152 サイズでも1MBを超える)ため、大量の画像データを保存しようとすればかなりストレージを圧迫します。
なので容量の軽いJPEGで保存しようとするわけですが、JPEGにはAI生成画像を保存する上で明確な弱点があります。メタデータに記録できる許容量が小さいのです。
ここで専門的な話をしますが、プロンプトや使用モデル等の生成画像の情報は通常メタデータに格納されます。ComfyUIとWebUI系でメタデータに保存される内容は違い、以下のようになります。
PNGの場合、ComfyUIでは PNG_INFO 内に prompt と workflow という二つのキーでそれぞれ情報が格納されます。このうち prompt の役割がよく分かっていないのですが、workflow のデータさえあればワークフローを完全再現することができます。
一方、WebUI系では parameters というキーでプロンプト等が格納されます。WebUI系はワークフローがそもそも存在しないため、少ないデータの格納で済みます。
JPEGの場合は Exif 内に格納されます。WebUI系は空いているタグ(調べていないので分かりませんが0xA40Bあたり?)内に "parameters: xxx..." という風にプロンプト等が記述されます。一方ComfyUIでは自環境においてはメタデータが保存されませんでした。
実はJPEGのExifは仕様上あまり多くのデータを保存することができません。なので比較的大きな容量であるワークフローのデータを格納しようとすると、うまくいかないという欠点があるのです。
先ほどの話に戻ると、特にComfyUIを使用する場合、JPEGではメタデータを保存できないということです。
2.それでもJPEGで保存したいとき
少し昔の話になりますが、ComfyUIで生成した画像をどうしてもJPEGで保存したかった私は、この問題をどうにか解決しました。
その方法はというと、PNGで出力した画像からワークフローのデータを抜き出しJSONファイルとして保存、画像をJPEGとして保存するというものでした。
PythonにはPNG_INFO操作が簡単にできるライブラリもあるので変換ツールは簡単に作れました。結果的に画像の容量は10分の1程度に圧縮され、ストレージにはだいぶ優しい状態になりました。しかし不満点も出てきました。
まず画像とワークフローの二つのファイルが生成されるため、ファイル数は単純に二倍になります。これがけっこう見た目がわちゃわちゃして見えるというか、やっぱりまとめたいよなーという欲が出てきてしまいました。
もう一つ、ワークフローデータが数百キロバイトあり、思ったよりも容量の圧縮が出来ていない点に気づきました。1MBの画像が100KBになっても、ワークフローが400KBほどで合計500KB程の場合、圧縮率は50%。これは一例ですが、このような感じでJPEGの恩恵をさほど受けられない現状にありました。
3.WEBPに移行
ウェッピーというふざけた名前のWEBPですが、可逆変換、不可逆変換どちらにも対応しており、圧縮率はそれぞれPNG、JPEG以上という優れもの。しかし対応ソフトウェアが少ないという点がネックです。
私の場合は、ClipStudioがWEBPに対応したこともあり「WEBP試してみようかな」となりました(ClipStudioのEWBP対応については色々言いたいことがあるがここでは語るまい)。
WEBPの場合、メタデータはJPEGと同じくExifに格納されます。pythonの getexif() で辞書データにすると、ComfyUIでいうところの prompt が272番、workflow が271番を使用しているようです。JPEGと同じように、それぞれ "prompt: xxx..." "workflow: xxx..." という文字列が格納されます。
JPEGと違うのは、容量制限がかなり緩和されていることです。具体的な数値は各自調べていただきたいですが、大量のノードを接続したワークフローも保存できました。通常扱う分には問題ないはずです。
で、生成するとワークフロー内蔵でファイルサイズはPNGの10分の1程度になりました。先ほど書いたJPEGとワークフローに分離したファイルも、WEBPに再変換するプログラムを書いてすべてWEBPにし、フォルダ内もだいぶスッキリしました。
仕組みが分からないのですが、JPEGと分離させたワークフローのJSONファイルは数百キロバイトあったのですが、WEBPに統合すると軽くなっているんです。JSONのヘッダ情報が多いとかなんでしょうかね?
4.プロンプト情報を追加保存できるようにした
ここまでで大体は満足したのですが、一つ問題が解決すると次の改善をしたくなるもの。
ComfyUIで保存したメタデータは先述の通りワークフローの形で再現されるため、WebUI系のようにプロンプトだけほしいときに探すのが面倒だったりします。プロンプト情報だけまとめたもの、ようはWebUI系の記述と同等のものを一緒に保存したくなったのです。
最初は comfy-image-saver (https://github.com/giriss/comfy-image-saver) 等を試していましたが、
comfy-image-saver
All the tools you need to save images with their generation metadata on ComfyUI. Compatible with Civitai & Prompthero geninfo auto-detection. Works with png, jpeg and webp. - giriss/comfy-image...
ワークフローが煩雑になってしまったり、WEBP出力すると自環境ではうまくいかなかったりしたので、結局自分でカスタムノードを作ることにしました。自作したカスタムノードはこちら↓
ComfyUI_mittimiLoadPreset2
This node can easily switch between models and prompts by saving presets. Compatible with SD1.5 and XL series. - mittimi/ComfyUI_mittimiLoadPreset2
自作のカスタムノードのメインは保存機能ではなくプリセットを活用するもので、これを作った話はまた別に書く予定です。
話を保存という点に戻すと、WebUI系のメタデータ記述自体は "parameters: xxx..." とすれば良いので、メタデータの270番に内容を格納することにしました。
ComfyUIの場合、プロンプトを記述するノードが複数になる場合が多いので、それらを上記のカスタムノードに集約して保存ノードに渡してあげる仕様にすることで、WebUI系と同等のプロンプト保存機能を得ることに成功しました。
というわけで現在は
①保存に適した軽いWEBPで
②ComfyUIにドラッグ&ドロップするとワークフローが再現でき
③WebUI系のプロンプトも見られる
画像を出力して運用しています。
ちなみにそれらの画像をランダム表示して、プロンプトやワークフローのコピーができるビューアもPythonで作りましたが、その話もまた今度。
0 件のコメント:
コメントを投稿