ComfyUIにおいて.jpgや.webpで画像を保存する方法（メタデータの扱いも含む）

この記事ではComfyUIで.pngの代わりに.jpgや.webpで保存する方法と、その中のワークフローを含んだメタデータの処理や移動について説明します。

尚、ここではComfyUIの基本について説明しません。既にComfyUIとComfyUI Managerをインストールしたという前提で進みます。

又、この前の記事で紹介した日本語化や日本語プロンプトを入力する方法は今回でも使うのでまずこのその記事もおすすめです。

https://qiita.com/phyblas/items/0c69ac370daa0aa01d15


# はじめに

ComfyUIはデフォルトでは.pngしか保存できないのですがね.pngファイルサイズが大きくてあまり不便に感じますね。そこで.jpgや.webpなどで保存できたらいいと思う人も少なくないでしょう。

ただ、ComfyUIから出力した.pngファイルは生成の時に使われたワークフローの情報を含んだメタデータが埋め込まれています。だからその画像をComfyUI画面にドラッグして入れたらワークフローのロードになって生成過程を再現できるから便利です。

そしてもしComfyUIから出力した.pngファイルをそのまま.jpgや.webpに変換したらその中のメタデータが失ってしまうのです。

それに、もしComfyUIで直接.jpgや.webpを保存できたらその方が便利なはずですよね。

方法を探してみたらメタデータも埋め込む.jpgや.webpで保存する方法色々を見つけたのでここで紹介したいと思います。


# 使えるプラグイン

実はそのようにことができるプラグインが複数ありますよね。例えば

<table>
<tr>
<td>Extended Save Image for ComfyUI</td>
<td><a href="https://github.com/palant/extended-saveimage-comfyui" target="_blank" rel="noopener">https://github.com/palant/extended-saveimage-comfyui</a></td>
</tr>
<tr>
<td>Save Image Extended for ComfyUI</td>
<td><a href="https://github.com/audioscavenger/save-image-extended-comfyui" target="_blank" rel="noopener">https://github.com/audioscavenger/save-image-extended-comfyui</a></td>
</tr>
<tr>
<td>SaveImgPrompt</td>
<td><a href="https://github.com/mpiquero1111/ComfyUI-SaveImgPrompt" target="_blank" rel="noopener">https://github.com/mpiquero1111/ComfyUI-SaveImgPrompt</a></td>
</tr>
<tr>
<td>ComfyUI Image Saver</td>
<td><a href="https://github.com/alexopus/ComfyUI-Image-Saver" target="_blank" rel="noopener">https://github.com/alexopus/ComfyUI-Image-Saver</a></td>
</tr>
<tr>
<td>Save Image Plus for ComfyUI</td>
<td><a href="https://github.com/Goktug/comfyui-saveimage-plus" target="_blank" rel="noopener">https://github.com/Goktug/comfyui-saveimage-plus</a></td>
</tr>
</table>

どれも名前が似ていて混乱しやすいですが、別のものです。

色々試したところExtended Save Image for ComfyUIとSave Image Extended for ComfyUIがいいと思うので、ここでこの2つの使い方を説明します。

違いとしては、Extended Save Image for ComfyUIはただ.jpgと.webpで保存できるようにするだけのものであるのに対し、Save Image Extended for ComfyUIの方は色んな機能が含まれています。機能が多いと使い勝手がよくて便利かもしれませんが、ノードが必要以上に大きくて複雑なので、もしただ簡単に.jpgか.webpで保存したいだけならExtended Save Image for ComfyUIでいいと思います。

*[2024/08/10補足]*:
ただし私が実際に使っているのは**Save Image Plus for ComfyUI**の方です。これはExtended Save Image for ComfyUIとほぼ同じですが、ノードの名前が違うのでSave Image Extended for ComfyUIとの衝突が避けられるという利点があります。


# プラグインのインストール

まずはインストールですが、ComfyUI Managerで簡単にできます。どれも「save image」とかで検索したら出てきます。名前が似ているので混同しやすいですね。

![comfyui16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/c05727c9-d096-5857-7ba6-153d31ff9909.png)

更にどれも`SaveImageExtended`という名前のノードなので同時にインストールすることができません。どちらか選びます。

# ノード追加

インストールして再起動したら`SaveImageExtended`ノードが追加できるようになります。

ダブルクリックで検索。
![comfyui17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/3552d7b7-81a3-ab0f-081b-1eb529a29ca6.png)

又は右クリックしてメニューから選びます。

![comfyui18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/52b36879-67d0-5b5c-14e5-4b7a97c92191.png)

Extended Save Image for ComfyUIの場合はこんな感じで小さいノードが出てきますね。ここで.jpgか.webpを選択できます。それだけです。

![comfyui19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/fb01fa90-d4a0-5195-ac6c-a784a26d5522.png)

Save Image Extended for ComfyUIの場合はこのようにいっぱい出てきますね。ここで出力画像について色々設定できますが、詳しいことは割愛します。

![comfyui20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/f2167579-5d47-a5e7-1f50-d8bf3bb9cbc8.png)

重要なのは拡張子を選択する項目です。これで.pngと.jpgと.webpだけでなく他にも色々できますね。

![comfyui21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/725b027e-3f45-66b8-dbf0-d8cb5afeae08.png)


# 使ってみる

使う時にただ元々`SaveImage`ノードだったところを`SaveImageExtended`で入れ替えるだけです。

簡単なためここではExtended Save Image for ComfyUIの方を使います。モデルは[MeinaMix](https://civitai.com/models/7240/meinamix)にします。これもよく使われているアニメ系モデルですね。

又、日本語プロンプトを入力できるように`DeepTranslatorCLIPTextEncodeNode`ノード（[前回の記事](https://qiita.com/phyblas/items/0c69ac370daa0aa01d15)参考）を`CLIPTextEncode`ノードの代わりに使います。

![comfyui22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/1b650190-82af-530f-db6b-fde3f05a6445.jpeg)

できた画像はこれです。

![ComfyUI_00053_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/196285de-e1c6-abe3-2d27-b7e6526bb7e5.jpeg)

これ画像をダウンロードして自分のComfyUIに入れたらワークフローが出てくるはずです。

ただしExtended Save Image for ComfyUIをインストールしておいていないと開けられません。

又Extended Save Image for ComfyUIとSave Image Extended for ComfyUIではメタデータが保存される場所は違うので、Extended Save Image for ComfyUIで保存した.jpgと.webpファイルはSave Image Extended for ComfyUIをインストールしても開けられません。逆も同じです。

このように.jpgと.webpの保存は標準化されていないのでプラグインを作る人それぞれによって差があるから、読み込みも保存もプラグイン依存という状態です。

.pngならComfyUI公式からのサポートだからこのような問題はなくていいですね。


# 画像の中に保存されたメタデータを覗いたり.jsonとして保存したりする

ComfyUIによって出力された画像の中のメタデータは色んな方法で覗くことができます。ここではPythonのPIL(pillow)を使います。ワークフローを.jsonとして個別で保存することもできます。

コードは以下です。
```python
from PIL import Image,PngImagePlugin
import json,os

filepath = '{{画像ファイル}}'
# pngで保存した場合
if(filepath.split('.')[-1].lower()=='png'):
    img = PngImagePlugin.PngImageFile(filepath)
    jdic = json.loads(img.info['workflow'])
# png以外の場合
else:
    img = Image.open(filepath)
    jexif = img._getexif()
    # Extended Save Image for ComfyUIで保存した場合
    if(37510 in jexif):
        jdic = json.loads(jexif[37510])['workflow']
    # Save Image Extended for ComfyUIで保存した場合
    else:
        jdic = json.loads(jexif[270][10:])
# jsonへ保存
with open(os.path.join(os.path.dirname(filepath),os.path.basename(filepath).split('.')[0]+'.json'),'w') as jf:
    json.dump(jdic,jf,indent=2,ensure_ascii=False)
```

pngだけはデータを保存する場所は違います。png以外はexifに保存されるということになります。Extended Save Image for ComfyUIとSave Image Extended for ComfyUIとはどれもexifに保存するが、ちょっと違うので互換性がないわけです。

### pngのメタデータの扱いの参考

- [PNG画像にメタデータをPythonで追加する](https://qiita.com/Limitex/items/f675f84e0227176d2abd)
- [png画像とjpg画像の取り扱いの注意点](https://qiita.com/miyamotok0105/items/0630c7f360c0207d8ed0)
- [PNGにメタデータを埋め込む](https://qiita.com/stoyosawa/items/8c0bc8ec31809be405a9)


# .pngから.jpgや.webpへ移行する

今まで.pngで保存していた画像でも今すぐ.jpgや.webpに変換することができます。

このコードを実行して全部.pngから.jpgへ変換することができます。
```python
from PIL import Image,PngImagePlugin
import json,glob,os

folder = '{{画像が保存れされたフォルダ}}'
for f in glob.glob(os.path.join(folder,'*.png')):
    img = PngImagePlugin.PngImageFile(f)
    jdic = {k: json.loads(v) for k,v in img.info.items()}
    jexif = Image.Exif()
    jexif[37510] = json.dumps(jdic)
    img.save(f.replace('.png','.jpg'),exif=jexif.tobytes())
```

ただし上述も書いた通り変換したらExtended Save Image for ComfyUIをインストールしないパソコンで使えないことになります。自分だけで使う場合は問題ないはずですが、他の人に渡したい時ワークフローをロードしにくくて不便だということになりますね。

でもこれで多少ハードディスクの余裕ができるでしょう。