画像の特定部分だけを抽出したい場合や、不要な背景を除去(クロッピング)したい場合は、crop() メソッドを使用します。
このメソッドで最も重要なのは、切り抜く範囲を指定する 4つの座標(タプル) の定義方法です。ここでは、正しい座標指定のルールと実装コードを解説します。
目次
実行可能なサンプルコード
以下のコードは、画像の一部を指定して切り抜き、新しい画像ファイルとして保存するスクリプトです。
from PIL import Image
import os
def crop_image_demo():
input_filename = "pillow_sample.jpg"
output_filename = "pillow_crop.jpg"
# 動作確認用の画像を作成(ファイルがない場合)
if not os.path.exists(input_filename):
create_test_image(input_filename)
try:
with Image.open(input_filename) as img:
print(f"Original Size: {img.size}")
# 切り抜き範囲の指定 (left, upper, right, lower)
# 例: 左上(400, 500) から 右下(525, 625) までの範囲
crop_area = (400, 500, 525, 625)
# 画像の切り抜き実行
# cropメソッドは、切り抜かれた新しいImageオブジェクトを返します
# ※元画像(img)は変更されません
cropped_img = img.crop(crop_area)
# 保存
cropped_img.save(output_filename)
print(f"Cropped image saved: {output_filename}")
print(f"Cropped Size: {cropped_img.size}")
except Exception as e:
print(f"エラーが発生しました: {e}")
def create_test_image(filename):
"""検証用の大きめの画像を作成(800x800)"""
img = Image.new("RGB", (800, 800), color=(200, 200, 200))
# 中心付近に目印を描画するなどの処理も可能ですが今回はシンプルに単色で
img.save(filename)
print(f">> テスト画像を作成しました: {filename}")
if __name__ == "__main__":
crop_image_demo()
解説:切り抜き範囲(ボックス)の指定方法
crop() メソッドの引数には、以下の4つの値をタプル (left, upper, right, lower) で渡します。
# (左端のx座標, 上端のy座標, 右端のx座標, 下端のy座標)
box = (400, 500, 525, 625)
image.crop(box)
座標のルール(重要)
PythonのPillowにおける座標系は、画像の左上が (0, 0) です。
- left (400): 切り抜き開始位置のX座標
- upper (500): 切り抜き開始位置のY座標
- right (525): 切り抜き終了位置のX座標(幅ではありません)
- lower (625): 切り抜き終了位置のY座標(高さではありません)
つまり、切り抜かれる画像のサイズ(幅・高さ)は以下の計算になります。
- 幅 (Width) =
right–left= 525 – 400 = 125px - 高さ (Height) =
lower–upper= 625 – 500 = 125px
「幅と高さ」を指定するのではなく、「右下隅の座標」を指定する点に注意してください。
