コーディングTips

透過PNGのつもりが、アルファチャンネルごと存在してなかった話

公開 約4分で読めます

目次5項目
  1. 動画に置いたら、背景が透明にならなかった
  2. PILで開いたら、そもそも透明チャンネルが無かった
  3. rembgで、後から本物の透過PNGに変換した
  4. 「透過っぽい見た目」と「本当の透過」は別物だった
  5. まとめ

横型のロング動画を作っていたときの話です。
冒頭に使う猫のキャラクターイラストをGeminiに「背景透過で」と頼んで生成してもらいました。
プレビューにはおなじみのチェック柄が表示されていて、てっきりちゃんと透過できているものだと思っていました。動画づくり自体は横型フォーマットに移ってから何本目かで慣れてきていたんですが、素材づくりの方でまた新しい落とし穴を踏むことになりました。

動画に置いたら、背景が透明にならなかった

生成した画像をRemotionの動画に配置してみると、猫のイラストの周りが透明にならず、チェック柄がそのまま四角く残った状態で表示されました。プレビュー画面のあのチェック柄は「透明であること」を示すエディタ側の表示のはずなのに、書き出した画像には模様として焼き込まれてしまっているような見た目でした。

最初は自分の実装ミスを疑いました。
Remotion側で透過PNGを読み込むときの指定を間違えているのかもしれない、CSS側で背景色を上から敷いてしまっているのかもしれない、と一通り確認しましたが、どちらのコードを見直しても問題は見当たりません。
念のため画像ビューアで元のPNGファイル単体を開いてみたら、そちらでもチェック柄がそのまま表示されました。ここでようやく、画像ファイル自体を疑う方向に切り替えました。

PILで開いたら、そもそも透明チャンネルが無かった

PythonのPillow(PIL)で画像を開いてimage.modeを確認したところ、返ってきたのはRGBAではなくRGBでした。透明度を持つはずのアルファチャンネル自体が、そもそも画像に存在していなかったんです。

念のため、画像の四隅のピクセル色も調べてみました。
すると単色のグレーが返ってきました。
つまりあのチェック柄は、そういう見た目の絵柄として普通に描画されていただけで、透明を表す特別な記号ではありませんでした。人間の目には「あ、透過素材だ」と映る配色でも、データの実態はただの不透明なPNGでした。

考えてみれば、画像生成AIの多くは写真やイラストを1枚のRGB画像として出力する仕組みが基本で、アルファチャンネルまで含めて生成する前提にはなっていないんだろうと思います。「透明といえばこのチェック柄」という見た目だけを学習して再現してしまえば、人間の目はそれっぽく騙されてしまいます。

💡 Tips: アルファチャンネルとは

画像の各ピクセルが持つ「不透明度」の情報です。
RGB(色の情報)にA(アルファ)が加わったRGBA形式が代表的ですが、PNGはグレースケール+アルファ(PILではLA)やパレット画像の透明色指定でも透過を表現できます。
いずれにせよ、こうしたアルファ情報を実際に持っている画像でないと、本当の意味で背景を透明にはできません。チェック柄の見た目だけでは、実際に透明かどうかは判断できません。

rembgで、後から本物の透過PNGに変換した

幸い、直し方自体はシンプルでした。
背景除去に特化したPythonのライブラリrembgを、そのモデルを動かす推論エンジンonnxruntimeと一緒にpip installし、生成済みの画像に対して背景除去だけを後から実行しました。
初回実行時には、u2netという学習済みモデル(176MB)が自動でダウンロードされる仕組みになっていて、これが実際の背景除去処理を担っています。生成し直す必要はなく、今あるファイルに対して1回コマンドを実行するだけで済みました。

処理後の画像をもう一度PILで確認すると、今度はmodeがちゃんとRGBAになっていて、猫のイラストの外側にあたるピクセルのアルファ値は0でした。動画に配置し直すと、想定していた通り背景が透けて表示されました。

「透過っぽい見た目」と「本当の透過」は別物だった

今回の件で改めて気づいたのは、画像生成AIに「背景透過で」と頼んだからといって、出力フォーマットやモデル次第では本当に透過にならないことがある、ということでした。プレビュー上のチェック柄は、人間に分かりやすく見せるための表示上の約束事にすぎず、画像データ自体が本当に透明かどうかとは別問題です。

これは以前、PNGを切り抜いたときに見えないアルファ値のノイズで余白が広がってしまった話を書いたときと、根っこが同じ話だなと思っています。
あのときは「見た目は透明なのに、データ上は透明じゃなかった」というズレで、今回は逆に「見た目は透過っぽいのに、データ上はそもそも透明の情報自体が無かった」というズレでした。方向は違いますが、どちらも画像を目で見ただけで判断せず、実際にデータを確認しないと気づけない種類の落とし穴です。

2回続けて似た構造のバグを踏んでみて、自分の中で1つの習慣ができました。
透過素材を扱うときは、見た目のチェック柄を信じるのではなく、まずimage.modeを出力してみる。この1行を挟むだけで、今回のような手戻りはかなり減らせそうです。

まとめ

AI画像生成の「背景透過」は、プレビューのチェック柄だけでは信じきれません。透過になっていなくてもrembgで後から直せると分かったので、次に同じ場面が来ても慌てずに済みそうです。

この記事が参考になったら、応援クリックをお願いします

Cat's Handこの記事を書いた人

Web制作歴10年以上。WordPressのテーマカスタマイズやコーディングを中心に、副業・本業ともにweb制作に携わっています。このブログでは、実際に手を動かして分かったことを書いています。