1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Python】 Pillowで始める画像処理入門 - 基本操作から実践まで

1
Posted at

はじめに

PILとPillowの関係

PIL (Python Imaging Library) は、Pythonで画像処理を行うための歴史あるライブラリです。しかし、PIL自体は2011年を最後に更新が止まってしまいました。

そこで登場したのが Pillow です。PillowはPILの後継プロジェクトとして開発され、現在も活発にメンテナンスされています。PillowはPILと互換性を保ちながら、新しいPythonバージョンや画像形式に対応しています。

Pillowでできること

Pillowを使うと、以下のような画像処理が可能になります。

  • 画像の入出力: JPEG、PNG、GIF、BMP、TIFFなど、多様な形式に対応
  • 画像の編集: リサイズ、回転、トリミング、反転
  • 画像の加工: フィルター適用、明るさ調整、カラーモード変換
  • 画像の生成: 新規画像の作成、図形や文字の描画

Webアプリケーションでのサムネイル生成、機械学習での画像前処理、データ分析での可視化など、幅広い場面で活用されています。

インストール方法

Pillowはpipコマンドで簡単にインストールできます。

pip install Pillow

インストール後、以下のコードで正しくインストールされたか確認できます。

from PIL import Image
print(Image.__version__)

コード内ではPILという名前でインポートしますが、これはPILとの互換性を保つための設計です。実際にインストールするのはPillowパッケージです。

Pillowの基本操作

画像の読み込みと保存

まずは画像ファイルを読み込んで、別の名前で保存してみましょう。

from PIL import Image

# 画像を読み込む
img = Image.open('sample.jpg')

# 画像を保存する
img.save('output.jpg')

Image.open()は画像ファイルを開き、画像オブジェクトを返します。このオブジェクトに対して様々な処理を行い、最後にsave()で保存します。

画像サイズの確認

画像の基本情報を確認する方法を見ていきましょう。

from PIL import Image

img = Image.open('sample.jpg')

# サイズ(幅, 高さ)
print(f"サイズ: {img.size}")  # 例: (1920, 1080)

# 幅と高さを個別に取得
width, height = img.size
print(f"幅: {width}px, 高さ: {height}px")

# 画像形式
print(f"形式: {img.format}")  # 例: JPEG

# カラーモード
print(f"モード: {img.mode}")  # 例: RGB

カラーモードは画像の色の表現方法を示します。

  • RGB: フルカラー(赤・緑・青の3チャンネル)
  • RGBA: フルカラー + 透明度
  • L: グレースケール(白黒)
  • 1: 二値画像(完全な白か黒)

画像形式の変換

異なる形式で保存する際は、save()の引数にファイル名を指定するだけです。拡張子から自動的に形式が判断されます。

from PIL import Image

# JPEGファイルを読み込む
img = Image.open('sample.jpg')

# PNG形式で保存
img.save('output.png')

# GIF形式で保存
img.save('output.gif')

特定の形式を明示的に指定することもできます。

# 形式を明示的に指定
img.save('output.png', format='PNG')

画像の編集

リサイズ(サイズ変更)

画像のサイズを変更する際はresize()メソッドを使います。

from PIL import Image

img = Image.open('sample.jpg')

# 新しいサイズを指定(幅, 高さ)
new_size = (800, 600)
img_resized = img.resize(new_size)

img_resized.save('resized.jpg')

高品質なリサイズを行う場合は、リサンプリングアルゴリズムを指定します。

# LANCZOSアルゴリズムで高品質リサイズ
img_resized = img.resize((800, 600), Image.Resampling.LANCZOS)

リサンプリングアルゴリズムは画像の品質を左右します。

  • LANCZOS: 最高品質(処理時間は長い)
  • BICUBIC: 高品質
  • BILINEAR: 標準的な品質
  • NEAREST: 最速だが品質は低い

アスペクト比(縦横比)を保ったままリサイズする場合はthumbnail()が便利です。

# アスペクト比を保ったまま、指定サイズ内に収める
img.thumbnail((800, 600))
img.save('thumbnail.jpg')

回転

画像を回転させるにはrotate()メソッドを使います。

from PIL import Image

img = Image.open('sample.jpg')

# 反時計回りに90度回転
img_rotated = img.rotate(90)
img_rotated.save('rotated_90.jpg')

# 時計回りに90度回転(-90度指定)
img_rotated = img.rotate(-90)
img_rotated.save('rotated_minus90.jpg')

# 45度回転
img_rotated = img.rotate(45)
img_rotated.save('rotated_45.jpg')

回転時に生じる余白を透明にするにはexpandオプションを使います。

# 画像全体が収まるようにキャンバスを拡大
img_rotated = img.rotate(45, expand=True)

より簡単に90度単位で回転させるにはtranspose()が便利です。

from PIL import Image

img = Image.open('sample.jpg')

# 反時計回りに90度
img_rotated = img.transpose(Image.ROTATE_90)

# 時計回りに90度
img_rotated = img.transpose(Image.ROTATE_270)

# 180度回転
img_rotated = img.transpose(Image.ROTATE_180)

トリミング(切り抜き)

画像の一部を切り出すにはcrop()メソッドを使います。引数には切り出す範囲を(左, 上, 右, 下)の形式で指定します。

from PIL import Image

img = Image.open('sample.jpg')

# 座標(100, 100)から(500, 500)までを切り出す
# (左, 上, 右, 下)
box = (100, 100, 500, 500)
img_cropped = img.crop(box)
img_cropped.save('cropped.jpg')

画像の中央部分を切り出す例を見てみましょう。

from PIL import Image

img = Image.open('sample.jpg')
width, height = img.size

# 中央の400x400ピクセルを切り出す
crop_size = 400
left = (width - crop_size) // 2
top = (height - crop_size) // 2
right = left + crop_size
bottom = top + crop_size

img_cropped = img.crop((left, top, right, bottom))
img_cropped.save('center_cropped.jpg')

反転

画像を反転させるにはtranspose()メソッドを使います。

from PIL import Image

img = Image.open('sample.jpg')

# 左右反転
img_flipped = img.transpose(Image.FLIP_LEFT_RIGHT)
img_flipped.save('flipped_lr.jpg')

# 上下反転
img_flipped = img.transpose(Image.FLIP_TOP_BOTTOM)
img_flipped.save('flipped_tb.jpg')

画像の加工

フィルターの適用

PillowにはImageFilterモジュールが用意されており、様々なフィルターを簡単に適用できます。

from PIL import Image, ImageFilter

img = Image.open('sample.jpg')

# ぼかし
img_blur = img.filter(ImageFilter.BLUR)
img_blur.save('blur.jpg')

# 輪郭検出
img_contour = img.filter(ImageFilter.CONTOUR)
img_contour.save('contour.jpg')

# シャープ化
img_sharp = img.filter(ImageFilter.SHARPEN)
img_sharp.save('sharp.jpg')

# エッジ強調
img_edge = img.filter(ImageFilter.EDGE_ENHANCE)
img_edge.save('edge_enhance.jpg')

より強いぼかし効果を得たい場合はGaussianBlurを使います。

# ガウシアンぼかし(radius=10)
img_blur = img.filter(ImageFilter.GaussianBlur(radius=10))

主なフィルターの種類は以下の通りです。

  • BLUR: 標準的なぼかし
  • GaussianBlur: ガウシアンぼかし(より自然)
  • SHARPEN: シャープ化
  • SMOOTH: 滑らかに
  • CONTOUR: 輪郭検出
  • EDGE_ENHANCE: エッジ強調
  • EMBOSS: エンボス効果

明るさ・コントラストの調整

画像の明るさやコントラストを調整するには、ImageEnhanceモジュールを使います。

from PIL import Image, ImageEnhance

img = Image.open('sample.jpg')

# 明るさを調整(1.0が元の明るさ)
enhancer = ImageEnhance.Brightness(img)
img_bright = enhancer.enhance(1.5)  # 1.5倍明るく
img_bright.save('bright.jpg')

img_dark = enhancer.enhance(0.5)  # 0.5倍暗く
img_dark.save('dark.jpg')

# コントラストを調整
enhancer = ImageEnhance.Contrast(img)
img_contrast = enhancer.enhance(2.0)  # コントラストを2倍に
img_contrast.save('high_contrast.jpg')

# 彩度を調整
enhancer = ImageEnhance.Color(img)
img_saturated = enhancer.enhance(1.5)  # 彩度を1.5倍に
img_saturated.save('saturated.jpg')

img_grayscale = enhancer.enhance(0.0)  # 彩度0でグレースケール
img_grayscale.save('desaturated.jpg')

enhance()メソッドの引数の意味は以下の通りです。

  • 1.0: 元の画像のまま
  • 1.0より大きい: 効果を強める
  • 0.0〜1.0: 効果を弱める
  • 0.0: 効果を完全に除去

カラーモードの変換

画像のカラーモードを変換するにはconvert()メソッドを使います。

from PIL import Image

img = Image.open('sample.jpg')

# グレースケール(白黒)に変換
img_gray = img.convert('L')
img_gray.save('gray.jpg')

# 二値画像(完全な白黒)に変換
img_bw = img.convert('1')
img_bw.save('bw.jpg')

# RGBからRGBAに変換(透明度チャンネルを追加)
img_rgba = img.convert('RGBA')
img_rgba.save('rgba.png')

主なカラーモードは以下の通りです。

  • RGB: フルカラー(24ビット)
  • RGBA: フルカラー + 透明度(32ビット)
  • L: グレースケール(8ビット)
  • 1: 二値画像(1ビット)
  • CMYK: 印刷用カラー

画像の生成

新規画像の作成

Pillowでは新しい画像を一から作成することもできます。

from PIL import Image

# 800x600の赤色画像を作成
img = Image.new('RGB', (800, 600), color='red')
img.save('red_image.jpg')

# RGB値で色を指定
img = Image.new('RGB', (800, 600), color=(100, 150, 200))
img.save('custom_color.jpg')

# 透明な画像を作成
img = Image.new('RGBA', (800, 600), color=(255, 255, 255, 0))
img.save('transparent.png')

Image.new()の引数は以下の通りです。

  1. カラーモード(RGBRGBAなど)
  2. サイズ(幅, 高さ)
  3. 背景色(オプション)

図形や文字の描画

画像に図形や文字を描画するには、ImageDrawモジュールを使います。

from PIL import Image, ImageDraw, ImageFont

# 白い背景の画像を作成
img = Image.new('RGB', (800, 600), color='white')

# 描画オブジェクトを作成
draw = ImageDraw.Draw(img)

# 長方形を描画
draw.rectangle((100, 100, 300, 200), fill='blue', outline='black', width=3)

# 円を描画
draw.ellipse((400, 100, 600, 300), fill='red', outline='black', width=3)

# 線を描画
draw.line((100, 400, 700, 400), fill='green', width=5)

# テキストを描画
draw.text((100, 500), 'Hello, Pillow!', fill='black')

img.save('drawing.jpg')

より大きなフォントでテキストを描画する場合は、フォントファイルを指定します。

from PIL import Image, ImageDraw, ImageFont

img = Image.new('RGB', (800, 600), color='white')
draw = ImageDraw.Draw(img)

# フォントを指定(サイズ40)
try:
    font = ImageFont.truetype('arial.ttf', 40)
except:
    # フォントが見つからない場合はデフォルトフォント
    font = ImageFont.load_default()

draw.text((100, 100), 'Hello, Pillow!', fill='black', font=font)
img.save('text_with_font.jpg')

描画できる図形の種類は以下の通りです。

  • rectangle(): 長方形
  • ellipse(): 楕円・円
  • line(): 直線
  • polygon(): 多角形
  • arc(): 円弧
  • text(): テキスト

実践的な使用例

サムネイル画像の一括生成

複数の画像を一括でサムネイル化する例を見てみましょう。

from PIL import Image
import os

def create_thumbnails(input_dir, output_dir, size=(200, 200)):
    """
    指定ディレクトリ内の全画像をサムネイル化
    
    Args:
        input_dir: 入力画像のディレクトリ
        output_dir: 出力先ディレクトリ
        size: サムネイルのサイズ(幅, 高さ)
    """
    # 出力先ディレクトリがなければ作成
    os.makedirs(output_dir, exist_ok=True)
    
    # 対応する画像形式
    extensions = ('.jpg', '.jpeg', '.png', '.gif', '.bmp')
    
    for filename in os.listdir(input_dir):
        if filename.lower().endswith(extensions):
            try:
                # 画像を開く
                img_path = os.path.join(input_dir, filename)
                img = Image.open(img_path)
                
                # サムネイル化(アスペクト比を保持)
                img.thumbnail(size, Image.Resampling.LANCZOS)
                
                # 保存(ファイル名に_thumbを追加)
                name, ext = os.path.splitext(filename)
                output_path = os.path.join(output_dir, f"{name}_thumb{ext}")
                img.save(output_path)
                
                print(f"処理完了: {filename}")
            except Exception as e:
                print(f"エラー({filename}): {e}")

# 使用例
create_thumbnails('images', 'thumbnails', size=(200, 200))

画像に透かし(ウォーターマーク)を追加

画像に透かし文字を追加する例です。

from PIL import Image, ImageDraw, ImageFont

def add_watermark(input_path, output_path, text='© 2024'):
    """
    画像に透かしテキストを追加
    
    Args:
        input_path: 入力画像のパス
        output_path: 出力先のパス
        text: 透かしテキスト
    """
    # 画像を開く
    img = Image.open(input_path).convert('RGBA')
    
    # 透明なレイヤーを作成
    txt_layer = Image.new('RGBA', img.size, (255, 255, 255, 0))
    
    # 描画オブジェクトを作成
    draw = ImageDraw.Draw(txt_layer)
    
    # フォントを設定
    try:
        font = ImageFont.truetype('arial.ttf', 50)
    except:
        font = ImageFont.load_default()
    
    # テキストのサイズを取得
    bbox = draw.textbbox((0, 0), text, font=font)
    text_width = bbox[2] - bbox[0]
    text_height = bbox[3] - bbox[1]
    
    # 右下に配置
    x = img.width - text_width - 20
    y = img.height - text_height - 20
    
    # 半透明の白文字で描画
    draw.text((x, y), text, fill=(255, 255, 255, 128), font=font)
    
    # レイヤーを合成
    watermarked = Image.alpha_composite(img, txt_layer)
    
    # RGB形式に変換して保存
    watermarked = watermarked.convert('RGB')
    watermarked.save(output_path)
    print(f"透かし追加完了: {output_path}")

# 使用例
add_watermark('sample.jpg', 'watermarked.jpg', '© 2024 Sample')

この例では、以下のテクニックを使っています。

  • 透明なレイヤーを作成してテキストを描画
  • alpha_composite()で元画像とレイヤーを合成
  • テキストの透明度を調整(fill=(255, 255, 255, 128)の128が透明度)

まとめ

Pillowは、Pythonで画像処理を行うための強力なライブラリです。この記事では以下の内容を解説しました。

基本操作

  • 画像の読み込み・保存
  • サイズや形式の確認
  • 画像形式の変換

画像の編集

  • リサイズとサムネイル化
  • 回転と反転
  • トリミング

画像の加工

  • フィルターの適用
  • 明るさ・コントラストの調整
  • カラーモードの変換

画像の生成

  • 新規画像の作成
  • 図形やテキストの描画

実践例

  • サムネイル画像の一括生成
  • 透かしの追加

Pillowは直感的なAPIを持ち、少ないコードで多様な画像処理が実現できます。Webアプリケーション、データ分析、機械学習など、様々な場面で活用してみてください。

より詳しい情報は公式ドキュメントをご覧ください。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?