このページでは、Python で PIL を用いて「画像の余白を削除する方法」について解説していきます。
今回紹介する方法を用いれば、下の画像のように絵の周りに不要な透明な余白がある場合、
この透明な余白を削除し、絵の部分のみの画像を取得することができます。
あくまでも取得できるのは矩形単位(長方形単位)で、絵の縁に沿うように取得できるわけではないので注意してください。
また、ほぼ同じ考え方で、透明度が設定されていない画像の不要な黒色・白色の余白を削除することも可能なので、これらについての方法も紹介していきます!
Contents
透明な余白を削除する方法:getbbox
と crop
を実行
まずは、透明度が設定された画像における「透明な余白を削除する方法」について解説します。
より具体的に言えば、この方法は「画像の縁付近の不要な透明画素を除去する方法」となります。
結論としては、PIL を用いて下記のような処理を実行することで、画像の縁付近の不要な余白を削除することが可能です。
from PIL import Image
# ファイルパスの設定
LOAD_PATH = "読み込みたい画像のファイルパス"
SAVE_PATH = "保存先の画像のファイルパス"
# 画像を読み込む
image = Image.open(LOAD_PATH)
# 不要な透明画素を除去
cropped_image = image.crop(image.getbbox())
# 画像を保存
cropped_image.save(SAVE_PATH)
上記スクリプトを実行すれば、LOAD_PATH
で設定されたパスの画像の「透明な余白を除去した画像」が SAVE_PATH
で設定されたパスに保存されます。
ただし、LOAD_PATH
で設定されたパスの画像に透明度が設定されていない場合、黒色の余白が除去されることになります。これについては後述の 黒色の余白を削除する方法:透明な余白を削除するときと同じ で解説します。
透明な余白の削除を行なっているのは、先程のスクリプトで太字で示した下記部分になります。
# 不要な透明画素を除去
cropped_image = image.crop(image.getbbox())
crop
メソッドでの不要な領域の削除
PIL には crop
メソッドが用意されており、画像から引数で指定した領域のみを切り出すことが可能です。つまり、領域外の画素を除去することができます。
ですので、画像の不要な余白(透明画素)を除いた領域を指定して crop
を実行すれば、不要な余白を除去することができることになります。
したがって、画像の不要な余白を除いた領域さえ取得できれば、後は crop
メソッドを実行すれば良いということになりますね!
スポンサーリンク
getbbox
での余白を除いた領域の取得
その領域の取得を行なっているのが getbbox
メソッドになります。
getbbox
メソッドでは、実行した画像オブジェクトに透明度が設定されている場合、透明でない画素が存在する矩形領域の座標を取得することができます。
したがって、getbbox
メソッドで取得した座標を引数に指定して crop
メソッドを実行すれば、その実行した画像オブジェクトから不要な余白を削除した結果を返却値として得ることができます。
もう少し具体的にいうと、画像での透明度はアルファチャンネルというデータで画素ごとに設定されており、ここで言う “透明な画素” とはアルファチャンネルが 0
に設定されている画素となります。つまり、完全に透明な画素です。
半透明な画素は getbbox
メソッドにおいて透明な画素とは見做されないので注意してください。
ちなみにアルファチャンネルについては下記ページの前半で解説していますので、詳しく知りたい方は下記ページをご参照いただければと思います。

黒色の余白を削除する方法:透明な余白を削除するときと同じ
透明な余白を削除する方法:getbbox と crop を実行 で紹介したスクリプトで LOAD_PATH
に透明度が設定された画像を指定した場合、その画像の透明な余白を削除することができました。
では、LOAD_PATH
に透明度が設定されない画像を指定した場合はどのようにスクリプトは動作するでしょうか?
この場合、黒色の余白が削除されることになります。
つまり、黒色の余白の削除は 透明な余白を削除する方法:getbbox と crop を実行 と同じ方法で実現することができることになります。
getbbox
メソッドでは、透明度が設定されている画像の場合、”透明でない画素が存在する矩形領域” の座標を取得することができます。その一方で、透明度が設定されていない画像の場合、getbbox
メソッドでは “黒色でない画素が存在する矩形領域” の座標が取得されます。
したがって、その座標を crop
メソッドの引数に指定して実行すれば、その領域以外を除去した画像を取得することができ、黒色の余白を削除することができることになります。
ちなみに “黒色の画素” とは、画素の R と G と B の値が全て 0
に設定されている画素となります。
白色の余白を削除する方法:色反転してから getbbox
を行う
ただ、余白は白色であることが多いので、黒色の余白が削除できてもそこまで旨みがありません。
では白色の余白を削除するにはどうすれば良いでしょうか?
これは、一旦画像の色を反転してから getbbox
メソッドを実行することで実現することができます。
具体的なスクリプトは下記のようになります。
from PIL import Image, ImageOps
# 読み込みたい画像のファイルパス
LOAD_PATH = "読み込みたい画像のファイルパス"
SAVE_PATH = "保存先の画像のファイルパス"
# 画像を読み込む
image = Image.open(LOAD_PATH)
# 色を反転した画像を生成
inverted_image = ImageOps.invert(image)
# 不要な白色画素を除去
cropped_image = image.crop(inverted_image.getbbox())
# 画像を保存
cropped_image.save(SAVE_PATH)
ImageOps.invert(image)
を実行することで、元画像の色を反転した画像を生成しています(ImageOps
を import
する必要があるので注意してください)。
したがって、元々白色の余白だった部分は黒色の余白に色が反転することになります。
ですので、あとは 黒色の余白を削除する方法:透明な余白を削除するときと同じ と同じ要領で、getbbox
メソッドでその黒色の余白を除いた矩形領域の座標を取得し、それを引数として元画像の画像オブジェクト image
に crop
メソッドを実行させれば、白色の余白を削除した画像を取得することができます。
あくまでも ImageOps.invert
を実行するのは getbbox
メソッドで座標を取得するためであり、最終的な crop
メソッドの実行は元画像の image
に実行させる必要があるので注意してください。
スポンサーリンク
まとめ
このページでは、Python で PIL を用いて「画像の余白を削除する方法」について解説しました!
透明な余白、黒色の余白、白色の余白ともに、getbbox
メソッドと crop
メソッドの利用により削除を実現することができます。
白色の余白の場合は getbbox
メソッド実行時に色の反転が必要なので注意してください。getbbox
メソッドで取得できる領域は、透明でない画素が存在する領域の矩形 or 黒色でない画素が存在する領域の矩形となります。
また、他の色の余白であっても、getbbox
メソッド実行前に余白を完全な黒色に加工した画像を作成してやれば、同様の方法で余白の削除が可能です。例えば背景の色と元画像の差分画像に対して getbbox
メソッドを実行してやれば、余白の削除が実現できそうですね!
getbbox
メソッドの解説ページ自体は少ないですが、割と活躍する場面が多いメソッドだと思いますので、是非このメソッドの意味合いや存在は覚えておいてください!