【日記#23】サンプル画像を一括で作ろうとしたら'brew update --auto-update'の罠
画像を販売するにあたって、サンプル画像を作成するのを失念していました。
サンプル画像とは参考にさせていただいた以下のサイトを見ていただければわかるのですが、
透かしの入った画像です。

これを一枚一枚、「Illustrator」等で編集するのは大変だと思い、また「Python」の力を借りることにしました。
上記の先日の記事同様、「OpenCV」を利用して合成しました。
コードはこちらです。
#ライブラリのインポート
import cv2
import numpy as np
import glob
import os
#カレントディレクトリからの相対パス(文頭の"./" 等は省略)
input_folderpath = "入力画像の相対パス"
output_folderpath = "出力画像の相対パス"
sukashi = cv2.imread("透かし画像の相対パス", cv2.IMREAD_UNCHANGED)
s_h,s_w=sukashi.shape[:2]
#文字の透明度
alpha = 0.1
files = glob.glob("./" + input_folderpath + "/*")
files = sorted(files, key=lambda f: os.stat(f).st_mtime)
for file in files:
filename = os.path.basename(file)
#画像の読み込み
img=cv2.imread(input_folderpath + '/' + filename, cv2.IMREAD_UNCHANGED)
img2 = cv2.resize(img, (s_w,s_h))
# 画像を合成する
img3 = cv2.addWeighted(img2, 1.0, sukashi, alpha, 0.0)
cv2.imwrite(output_folderpath + '/' + os.path.splitext(filename)[0] + '_sample2.png', img3)そして、実行すると

やった楽ちん!
と思ったのですが、なんか文字が目立つなと
そして、よく見ると

アンチエイリアスになってないし、所々汚い…
これを解決しようとしたのですが、なかなか解決法が見つからないというか、何が問題なのかがいまいち分からなかったのでChatGPTにどう聞いていいかも分からず、数時間同様の症状を調べたりして分からなかったので
「OpenCV」を諦めて、 Pythonの画像処理ライブラリ「Pillow」を使用することにしました。
しかし、
ModuleNotFoundError: No module named 'PIL' homebrewとエラーが出てしまい、私はmacユーザーで「Homebrew」を使用しているので
ユーザー名@コンピュータ名 ~ & brew install pillowとターミナルに打ち込むと
Running 'brew update --auto-update'...と表示されてアップデートが始まりました。
数分間で終わって、いざ実行してみると「import cv2」消しておらず、
ユーザー名@コンピュータ名 ~ % /opt/homebrew/bin/python3 /Users/ユーザー名/TestPython/透かし.py
Traceback (most recent call last):
File "/users/ユーザー名/TestPython/透かし.py", line 2, in <module>
import cv2
File "/opt/homebrew/lib/python3.12/site-packages/cv2/__init__-py", line 181, in <module>
bootstrap ()
File "/opt/homebrew/lib/python3.12/site-packages/cv2/__init__-py", line 153, in bootstrap
native_module = importlib. import_module("cv2")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/python@3.12/3.12.3/Frameworks/Python.framework/Versions/3.12/1ib/python3.12/importlib/__init__.py", line 90, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ImportError: dlopen(/opt/homebrew/Cellar/opencv/4.9.0_7/lib/python3.12/site-packages/cv2/python-3.12/cv2.cpython-312-darwin.so, 0x0002): Library not loaded: / opt/homebrew/opt/ffmpeg@6/lib/libavcodec.60.dylib
Referenced from: <********-****-****-****-************> /opt/homebrew/Cellar/opencv/4.9.0_7/lib/libopencv_videoio.4.9.0.dylib
Reason: tried: '/opt/homebrew/opt/ffmpeg@6/lib/libavcodec-60 dylib' (no such file),
ile),'/System/Volumes/Preboot/Cryptexes/0S/opt/homebrew/opt/ffmpeg@6/lib/libavcodec.60 dylib' (no such file)'/opt/homebrew/opt/ffmpeg@6/lib/libavcodec.60 dylib' (no such file),'/opt/homebrew/Cellar/ffmpeg/7.0/lib/libavcodec.60 dylib' (no such file),'/System/Volumes/Preboot/Cryptexes/OS/opt/homebrew/Cellar/ffmpeg/7.0/lib/libavcodec.60.dylib' (no such file),'/opt/homebrew/Cellar/ffmpeg/7.0/lib/libavcodec.60 dylib' (no such file)という長々エラーを吐き、
今回は「OpenCV」を使用しないので大丈夫かもしれませんが、
「Midjourney」画像分割等で使っているため解決する必要があります。
エラーを見る感じ「(no such file)」と書いてあることからパスが通っていない感じなのかとは思いましたが、アップデート前までは普通に使えていたので、急にパスが通らなくなるのだろうかということと、
おそらく、何かが原因でパスが通らなくなったことが考えられるため、根本的な原因を解決しなけば、他のモジュールのパスも通ってないものがある可能性を考えました。
ここで、AIを利用して即解決!!!
ならかっこいいんですが、私はまだそこまで使いこなせていないのと、この現象の言語化が難しい気がしました。
パスが通ってないと言えば、
「.zshrcファイル等に追記してパスを通そう!」
と言われるのが関の山だと思いますが、かといってパスが通っていないこと以外の原因を聞いた場合、
「OpenCV」がインストールされてないとか、
「Homebrew」や「Visual Studio Code」の再インストールを勧められるくらいだろうと思って思考停止しましたね。
まあ、人とAIの回答は多分違うので、自分の経験を信じず「ChatGPT」に聞いてみればすぐ解決できたかもしれないなと今更ながら思います。
ふと思いついては、ちまちま検索していると以下の記事を見つけました。
まあ、「Raspberry Pi」でも「linux」でもない環境なんですが、このままいくつかのモジュールのパスを手動で通すか全再インストールはめんどくさいと思ったので、藁にもすがる思いで片っ端から見てました。

https://isc.tamu.edu/~lewing/linux/
その記事を読んで見ると、

調べてみると、OpenCVはnumpyを利用しているようで、
numpyに不具合があっても、動かないということです。
ということで、更新しても解決したとは思いますが、
念のためにnumpyを再インストールしたら普通に治りました。

https://www.youtube.com/watch?v=FtnqWPPF3g4
気を取り直して、「Pillow」でサンプル画像を作りました。
コードは以下になります。
#ライブラリのインポート
import glob
import os
from PIL import Image
#カレントディレクトリからの相対パス(文頭の"./" 等は省略)
input_folderpath = "入力画像の相対パス"
output_folderpath = "出力画像の相対パス"
sukashi = Image.open( "透かし画像の相対パス")
files = glob.glob("./" + input_folderpath + "/*")
files = sorted(files, key=lambda f: os.stat(f).st_mtime)
for file in files:
filename = os.path.basename(file)
#画像の読み込み
img = Image.open(input_folderpath + '/' + filename)
img2 = img.resize(sukashi.size)
img2.putalpha(255)
img3 = Image.alpha_composite(img2, sukashi)
img3.save(output_folderpath + '/' + os.path.splitext(filename)[0] + '_sample.png')そして、実行すると

綺麗に生成されました。
良かった。
でも、今日の出来事でプログラミングには柔軟な頭が必要だなと感じましたね。

そういえば、昨日の記事書いた時に思ったんですよね。
この内容、日記以外の投稿ができてから公開した方が変なフラグ立たなくていいのではないかと、
なぜかというと、万が一何か問題が発生して完成に至らなかったら良くないからです。
だから、今日の出来事はある意味フラグ回収した感じですね…
(フラグ回収…素早い)
それでは次の投稿もお楽しみに!!!
