PeperspeceでSuperMergerのSequential XY Merge and Generation がグリッド画像を表示しない
[2023/06/25追記]スクリプトを書き換えないスマートな方法
だにえるさんに感謝🙏
pip install fonts
pip install roboto
pip install font_roboto
はじめまして
どうも、朝霧ちしゃです。note初投稿です。
Web-UIの拡張機能が増えすぎて、何をやったかわけわからなくなりがちなので備忘録的にやったことを残していこうと思います。
当方、プログラマではありませんゆえ、間違った情報を書いてしまうこともあると思いますが、その時は温かくコメントで指摘していただければ幸いです。
不具合の内容
今回遭遇した不具合は、タイトルにもある通り
Automatic1111版Stable-Diffusion web UIにてマージを行う便利な拡張、hako-mikan/sd-webui-supermerger
Sequential XY Merge and Generation 機能が、
"NameError: name 'roboto_ttf_file' is not defined"
エラーを起こし、グリッド画像を表示できないという症状です。
新計算方法のTensorを試していて、複数の混ぜパターンを試そうとしたところグリッドの生成結果が表示されない現象にブチ当たってしまいました!
しかし、個別に画像は生成されているのでどうやらグリッド画像の作成に失敗しているようです。
とりあえずエラーを見てみましょう。
エラー全文
Traceback (most recent call last):
File "/storage/stable-diffusion/stable-diffusion-webui/extensions/sd-webui-supermerger/scripts/mergers/mergers.py", line 561, in get_font
from fonts.ttf import Roboto
ModuleNotFoundError: No module named 'fonts'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/storage/stable-diffusion/stable-diffusion-webui/extensions/sd-webui-supermerger/scripts/mergers/mergers.py", line 568, in get_font
return ImageFont.truetype(shared.opts.font or 'javascript/roboto.ttf', fontsize)
File "/usr/local/lib/python3.10/dist-packages/PIL/ImageFont.py", line 996, in truetype
return freetype(font)
File "/usr/local/lib/python3.10/dist-packages/PIL/ImageFont.py", line 993, in freetype
return FreeTypeFont(font, size, index, encoding, layout_engine)
File "/usr/local/lib/python3.10/dist-packages/PIL/ImageFont.py", line 248, in __init__
self.font = core.getfont(
OSError: cannot open resource
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.10/dist-packages/gradio/routes.py", line 414, in run_predict
output = await app.get_blocks().process_api(
File "/usr/local/lib/python3.10/dist-packages/gradio/blocks.py", line 1323, in process_api
result = await self.call_function(
File "/usr/local/lib/python3.10/dist-packages/gradio/blocks.py", line 1051, in call_function
prediction = await anyio.to_thread.run_sync(
File "/usr/local/lib/python3.10/dist-packages/anyio/to_thread.py", line 31, in run_sync
return await get_asynclib().run_sync_in_worker_thread(
File "/usr/local/lib/python3.10/dist-packages/anyio/_backends/_asyncio.py", line 937, in run_sync_in_worker_thread
return await future
File "/usr/local/lib/python3.10/dist-packages/anyio/_backends/_asyncio.py", line 867, in run
result = context.run(func, *args)
File "/storage/stable-diffusion/stable-diffusion-webui/extensions/sd-webui-supermerger/scripts/mergers/xyplot.py", line 52, in numanager
result,currentmodel,xyimage,a,b,c= sgenxyplot(xtype,xmen,ytype,ymen,esettings,
File "/storage/stable-diffusion/stable-diffusion-webui/extensions/sd-webui-supermerger/scripts/mergers/xyplot.py", line 350, in sgenxyplot
grid = smakegrid(xyimage,xs,ys,gridmodel,image_temp[4])
File "/storage/stable-diffusion/stable-diffusion-webui/extensions/sd-webui-supermerger/scripts/mergers/xyplot.py", line 367, in smakegrid
grid = draw_origin(grid, currentmodel,w*len(xs),h*len(ys),w)
File "/storage/stable-diffusion/stable-diffusion-webui/extensions/sd-webui-supermerger/scripts/mergers/mergers.py", line 575, in draw_origin
fnt = get_font(fontsize)
File "/storage/stable-diffusion/stable-diffusion-webui/extensions/sd-webui-supermerger/scripts/mergers/mergers.py", line 570, in get_font
return ImageFont.truetype('javascript/roboto.ttf', fontsize)
File "/usr/local/lib/python3.10/dist-packages/PIL/ImageFont.py", line 996, in truetype
return freetype(font)
File "/usr/local/lib/python3.10/dist-packages/PIL/ImageFont.py", line 993, in freetype
return FreeTypeFont(font, size, index, encoding, layout_engine)
File "/usr/local/lib/python3.10/dist-packages/PIL/ImageFont.py", line 248, in __init__
self.font = core.getfont(
OSError: cannot open resource
生成環境
Peperspece gradient
コンテナ:cyberes/gradient-base-py3.10:latest
やったこと
結論!コードを書き換えた!
scripts/mergers/mergers.py 556行目 draw_origin
・変更前
def draw_origin(grid, text,width,height,width_one):
grid_d= Image.new("RGB", (grid.width,grid.height), "white")
grid_d.paste(grid,(0,0))
def get_font(fontsize):
try:
from fonts.ttf import Roboto
try:
return ImageFont.truetype(opts.font or Roboto, fontsize)
except Exception:
return ImageFont.truetype(Roboto, fontsize)
except Exception:
try:
return ImageFont.truetype(shared.opts.font or 'javascript/roboto.ttf', fontsize)
except Exception:
return ImageFont.truetype('javascript/roboto.ttf', fontsize)
d= ImageDraw.Draw(grid_d)
color_active = (0, 0, 0)
fontsize = (width+height)//25
fnt = get_font(fontsize)
if grid.width != width_one:
while d.multiline_textsize(text, font=fnt)[0] > width_one*0.75 and fontsize > 0:
fontsize -=1
fnt = get_font(fontsize)
d.multiline_text((0,0), text, font=fnt, fill=color_active,align="center")
return grid_d
・変更後
def draw_origin(grid, text,width,height,width_one):
grid_d= Image.new("RGB", (grid.width,grid.height), "white")
grid_d.paste(grid,(0,0))
roboto_ttf_file = '/storage/stable-diffusion/stable-diffusion-webui/modules/Roboto-Regular.ttf'
def get_font(fontsize):
try:
return ImageFont.truetype(opts.font or roboto_ttf_file, fontsize)
except Exception:
return ImageFont.truetype(roboto_ttf_file, fontsize)
# try:
# from fonts.ttf import Roboto
# try:
# return ImageFont.truetype(opts.font or Roboto, fontsize)
# except Exception:
# return ImageFont.truetype(Roboto, fontsize)
# except Exception:
# try:
# return ImageFont.truetype(shared.opts.font or 'javascript/roboto.ttf', fontsize)
# except Exception:
# return ImageFont.truetype('javascript/roboto.ttf', fontsize)
d= ImageDraw.Draw(grid_d)
color_active = (0, 0, 0)
fontsize = (width+height)//25
fnt = get_font(fontsize)
if grid.width != width_one:
while d.multiline_textsize(text, font=fnt)[0] > width_one*0.75 and fontsize > 0:
fontsize -=1
fnt = get_font(fontsize)
d.multiline_text((0,0), text, font=fnt, fill=color_active,align="center")
return grid_d
どうしてそうなった?
まずエラーを下から見ていくと、
`OSError: cannot open resource`
リソースを開けないよ、というエラーのようです。
何を読み込めなかったんじゃ!ということで、もっと上を見ていくと
`ModuleNotFoundError: No module named 'fonts'`
というエラーがでてました。
これは'fonts'モジュールが見つからないよというエラーです。
じゃあとりあえず pip install fonts すればいいね!
となったところで、アレ? X/Y/Z Prot 機能は動いてるんだよな・・・ということに気づきます。
web-uiの X/Y/Z Prot 機能の実装は scripts/xyz_grid.py です。
ここからテキストの作成機能を探していくと、
141行目に draw_grid_annotations というグリッドの注釈を書き込む機能がありました。
draw_grid_annotations が定義されているのは、modules/images.py です。
その中で get_font を呼んでいて、定義は27行目にありました。
def get_font(fontsize: int):
try:
return ImageFont.truetype(opts.font or roboto_ttf_file, fontsize)
except Exception:
return ImageFont.truetype(roboto_ttf_file, fontsize)
roboto_ttf_file は modules/paths_internal.py で定義されています。
roboto_ttf_file = os.path.join(modules_path, 'Roboto-Regular.ttf')
modulesディレクトリを見てみると Roboto-Regular.ttf というフォントファイルがおかれてました。
じゃあ同じように書き換えれば動くじゃろ。ってことで書き換えたコードが上記の変更後になります。
一応、fontsモジュールも入れてみたんですが、結局Robotoファイルがないよってなりました・・・
今回はコード書き換えで動いたのでヨシ!としました。
まとめ
以上、PeperspeceでSequential XY Mergeがグリッド画像を生成しない件を解決した時の備忘録でした。
拡張が更新される度、書き直さないといけないので、なんかもっとスマートな解決方法があればなあとは思います。
paperspaceでやるといろいろローカルにはない不具合が出たりして大変ですね・・・(学習とか・・・
最後までお読みいただきありがとうございました!
TwitterやPixivではツインテールの女の子をメインに上げてますのでよかったら一度覗いてみてください!
Pixiv:https://www.pixiv.net/users/85793425