Python Pillow徹底ガイド|画像処理の基本から応用まで完全解説

1. はじめに

PythonとPillowの概要

Pythonは、多くのプログラマーやデータサイエンティストに愛用されるプログラミング言語で、そのシンプルな構文と多様なライブラリにより、さまざまな用途で利用されています。その中でも、画像処理に特化したPillow(以前のPIL: Python Imaging Library)は、Pythonの代表的な画像処理ライブラリとして広く使われています。

Pillowは、JPEGやPNG、GIFといったさまざまな画像フォーマットをサポートし、リサイズ、トリミング、フィルタリング、テキストの追加など、幅広い画像操作が可能です。多くのアプリケーションやプロジェクトで、画像の読み込みや保存、編集が必要な場合に利用されています。

この記事の目的

この記事では、PythonのPillowライブラリを使った基本的な画像処理から、応用的な操作までを徹底的に解説していきます。具体的には、画像の読み込みや保存といった基本操作から、画像のリサイズや回転、フィルタ処理、さらにはテキストの描画や画像合成まで、多岐にわたる画像操作の方法を紹介します。

これを読むことで、Pillowの使い方を一通りマスターし、実際のプロジェクトで活用できる知識とスキルを得ることができるでしょう。

2. Pillowのインストール方法

2.1 PillowをPython環境にインストールする方法

Pillowを使用するためには、まずPython環境にライブラリをインストールする必要があります。インストール方法は非常に簡単で、以下のコマンドをターミナル(Windowsの場合はコマンドプロンプト)に入力するだけで完了します。

pip install Pillow

pipは、Pythonパッケージを管理するためのツールで、このコマンドを実行することで、Pillowライブラリが自動的にインストールされます。インストールが成功すると、画像の操作が可能になります。

2.2 動作確認の方法

Pillowのインストールが完了したら、簡単なコードを実行して、正常に動作しているか確認しましょう。以下のコードをPythonのスクリプトファイルに書き込み、実行してみてください。

from PIL import Image

# Pillowの動作確認用コード
img = Image.new('RGB', (100, 100), color = 'red')
img.save('test_image.png')

このコードでは、100×100ピクセルの赤い画像を作成し、”test_image.png”という名前で保存しています。この画像ファイルが正しく作成されていれば、Pillowが正常にインストールされ、動作していることが確認できます。

2.3 よくあるインストールの問題と解決策

時折、Pillowのインストール中に問題が発生する場合があります。以下は、よくあるトラブルとその解決策です。

  1. Pythonのバージョンが古い場合
    PillowはPython 3.x以降をサポートしています。古いバージョンのPythonを使用している場合、Pillowが正常にインストールできないことがあります。python --versionを使ってバージョンを確認し、必要に応じて最新版にアップデートしましょう。
  2. 依存パッケージの問題
    Pillowのインストール時に、必要な依存パッケージが不足していることがあります。この場合、エラーメッセージに従って足りないパッケージを個別にインストールするか、以下のように依存パッケージを自動でインストールするオプションを付け加えることができます。
   pip install Pillow --upgrade
  1. 環境変数の設定
    特にWindows環境でPillowが正しく動作しない場合、PythonやPipのパスが環境変数に正しく設定されていないことが原因である場合があります。これを確認して、正しいパスが設定されていることを確認しましょう。

3. 画像の読み込みと表示

3.1 画像ファイルをPythonで読み込む方法

画像の読み込みは、Pillowライブラリを使った画像処理の基本的なステップです。まずは、指定したファイルを読み込む方法を紹介します。Pillowでは、Image.open()メソッドを使用して画像を開くことができます。

以下は、画像を読み込むための基本的なコードです。

from PIL import Image

# 画像ファイルの読み込み
img = Image.open('sample.jpg')

# 画像の情報を表示
print(img.format)  # ファイル形式(例: JPEG, PNG)
print(img.size)    # サイズ(幅, 高さ)
print(img.mode)    # 色モード(例: RGB, L)

このコードでは、Image.open()を使って画像ファイルを開き、その画像のフォーマット、サイズ、色モードなどの情報を取得しています。ファイルのパスを指定するだけで簡単に画像を読み込めるため、非常に便利です。

3.2 画像を表示する

画像を読み込んだ後、その画像を表示するには、show()メソッドを使用します。このメソッドは、読み込んだ画像をシステムのデフォルトビューアで表示するために使われます。

以下のコードで、画像を表示する方法を確認しましょう。

from PIL import Image

# 画像ファイルの読み込み
img = Image.open('sample.jpg')

# 画像の表示
img.show()

このコードでは、指定した画像ファイルがデフォルトの画像ビューアに表示されます。これにより、画像の内容を確認しながら、後続の処理に進むことが可能です。

3.3 画像の詳細情報の取得

Pillowでは、画像のさまざまな情報を取得することができます。例えば、画像の幅や高さをsize属性で確認でき、色モードをmode属性で確認できます。

以下のように、画像の幅や高さ、ファイル形式を簡単に取得することができます。

from PIL import Image

# 画像ファイルの読み込み
img = Image.open('sample.jpg')

# 画像の詳細情報を表示
print(f'画像のサイズ: {img.size}')   # (幅, 高さ)
print(f'ファイル形式: {img.format}') # 画像フォーマット(JPEG, PNGなど)
print(f'色モード: {img.mode}')       # 色モード(RGB, Lなど)

これにより、読み込んだ画像の基本情報を取得し、後続の処理に利用できます。例えば、画像の幅や高さを取得して、そのサイズに応じたリサイズやトリミングを行う際に非常に役立ちます。

3.4 Pillowでサポートされている画像フォーマット

Pillowは、以下のような多くの画像フォーマットに対応しています。

  • JPEG
  • PNG
  • GIF
  • BMP
  • TIFF

そのため、ほとんどの一般的な画像形式をPillowで読み込み、操作することが可能です。例えば、ウェブアプリケーションでユーザーからアップロードされた画像を処理する際、フォーマットを気にせず幅広い形式に対応できるため、柔軟に対応できます。

4. 基本的な画像処理

4.1 画像のリサイズ

画像処理の基本操作のひとつに、画像のリサイズがあります。リサイズは、画像の解像度を変更するために使用され、ウェブサイトやアプリケーションで適切なサイズに合わせる際に便利です。Pillowでは、resize()メソッドを使って簡単に画像のサイズを変更できます。

以下は、画像のリサイズを行うためのコード例です。

from PIL import Image

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

# 画像のリサイズ (幅400px、高さ300px)
resized_img = img.resize((400, 300))

# リサイズした画像を保存
resized_img.save('resized_sample.jpg')

このコードでは、画像を読み込み、そのサイズを (400, 300) にリサイズしています。リサイズ後は、ファイルとして保存されます。これにより、必要に応じたサイズで画像を出力することが可能です。

4.2 画像のトリミング

トリミングは、画像の一部を切り抜く操作です。例えば、画像内の特定の領域だけを取り出して使用したい場合に便利です。Pillowでは、crop()メソッドを使って画像の指定範囲を切り抜くことができます。

以下は、トリミングのコード例です。

from PIL import Image

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

# 画像をトリミング (左上座標100, 100から右下座標300, 300まで)
cropped_img = img.crop((100, 100, 300, 300))

# トリミングした画像を保存
cropped_img.save('cropped_sample.jpg')

このコードでは、crop()メソッドを使って画像の特定の範囲を指定し、その部分だけを切り抜いて保存しています。

4.3 画像の回転

画像の回転は、回転角度を指定するだけで簡単に行うことができます。Pillowのrotate()メソッドを使用すれば、指定した角度に従って画像を回転させることができます。回転後に画像が一部欠けてしまう場合は、expand=True オプションを使用して、画像全体が表示されるように拡張することができます。

以下は、画像を45度回転させるコード例です。

from PIL import Image

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

# 画像を45度回転させる (サイズを拡張して切れないようにする)
rotated_img = img.rotate(45, expand=True)

# 回転した画像を保存
rotated_img.save('rotated_sample.jpg')

このコードでは、画像が45度回転され、expand=True の指定により、回転後も画像全体が保存されています。

4.4 画像の反転

画像を左右や上下で反転させることも、Pillowでは簡単にできます。例えば、水平反転(左右反転)や垂直反転(上下反転)は、transpose()メソッドを使って実行します。

以下は、画像を左右に反転するコード例です。

from PIL import Image

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

# 画像を左右反転
flipped_img = img.transpose(Image.FLIP_LEFT_RIGHT)

# 反転した画像を保存
flipped_img.save('flipped_sample.jpg')

このコードでは、指定された画像が左右に反転され、保存されています。

4.5 Pillowでサポートされるその他の基本処理

Pillowでは、リサイズやトリミング、回転や反転だけでなく、さまざまな画像処理をサポートしています。例えば、画像の明るさやコントラストの調整、色空間の変換なども簡単に行うことができます。これにより、複雑な画像編集もプログラムで自動化することが可能です。

5. 画像のフォーマット変換と保存

5.1 画像フォーマットの変換

Pillowを使うと、画像のフォーマットを簡単に変換できます。例えば、JPEG形式の画像をPNG形式に変換することが可能です。フォーマットの変換は、画像ファイルを読み込み、save()メソッドで新しいフォーマットを指定するだけで行えます。

以下は、JPEG画像をPNG形式に変換する例です。

from PIL import Image

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

# PNG形式で保存する
img.save('converted_image.png', 'PNG')

このコードでは、sample.jpgというJPEG形式の画像を読み込み、converted_image.pngというPNG形式のファイルに保存しています。このようにして、異なる画像フォーマット間での変換が非常に簡単に実行できます。

5.2 画像の保存方法

Pillowで画像を処理した後、その画像を保存する際には、さまざまなオプションが用意されています。例えば、JPEG形式で保存する際に、画像の品質や最適化、プログレッシブJPEGなどの設定をカスタマイズすることができます。

以下は、JPEG画像を保存する際に品質と最適化オプションを指定する例です。

from PIL import Image

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

# JPEG形式で保存(品質95、最適化あり)
img.save('optimized_image.jpg', 'JPEG', quality=95, optimize=True)

このコードでは、quality=95 で画像の品質を指定し、optimize=True で画像を最適化して保存しています。品質の値は0〜100の範囲で指定でき、数値が大きいほど高品質で保存されますが、ファイルサイズも大きくなります。また、optimize=Trueを指定することで、ファイルサイズを可能な限り小さくするようにPillowが最適化を行います。

5.3 プログレッシブJPEGの保存

プログレッシブJPEGは、インターネット上で段階的に画像が表示される形式です。ページが完全に読み込まれる前に、低解像度から高解像度へと段階的に表示されるため、ユーザーエクスペリエンスを向上させることができます。

PillowでプログレッシブJPEGを保存するには、progressive=True オプションを指定します。

from PIL import Image

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

# プログレッシブJPEGで保存
img.save('progressive_image.jpg', 'JPEG', quality=85, progressive=True)

このコードでは、progressive=True を指定してJPEG画像を保存することで、プログレッシブJPEGとして出力しています。これにより、ウェブページの読み込み中に画像が段階的に表示されるようになります。

5.4 EXIF情報の保持

EXIF(Exchangeable Image File Format)は、デジタルカメラなどで撮影された画像に埋め込まれるメタデータです。例えば、撮影日時やカメラの設定、GPS情報などが含まれます。Pillowでは、EXIF情報を保持したまま画像を保存することができます。

以下は、EXIF情報を保持して画像を保存する例です。

from PIL import Image

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

# EXIF情報を取得
exif_data = img.info.get('exif')

# EXIF情報を保持してJPEG形式で保存
img.save('exif_image.jpg', 'JPEG', exif=exif_data)

このコードでは、元の画像に含まれていたEXIF情報を取得し、そのまま保存しています。これにより、カメラや撮影条件に関する情報が失われることなく画像を保存することができます。

6. 画像へのフィルターやエフェクトの適用

6.1 画像の明るさやコントラストの調整

Pillowを使うと、画像の明るさやコントラストを簡単に調整することができます。これには、ImageEnhanceモジュールが便利です。ImageEnhance.Brightness()ImageEnhance.Contrast()を使用することで、画像の視覚効果を調整できます。

以下は、明るさを調整するコード例です。

from PIL import Image, ImageEnhance

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

# 明るさを調整(1.5倍明るくする)
enhancer = ImageEnhance.Brightness(img)
bright_img = enhancer.enhance(1.5)

# 調整後の画像を保存
bright_img.save('bright_sample.jpg')

このコードでは、enhance(1.5)を使って画像を1.5倍明るくしています。enhance()の引数には明るさの倍率を指定でき、1.0が元の明るさ、1.0未満で暗く、1.0以上で明るくなります。

同様に、コントラストの調整も以下のように行えます。

from PIL import Image, ImageEnhance

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

# コントラストを調整(2.0倍に強調)
enhancer = ImageEnhance.Contrast(img)
contrast_img = enhancer.enhance(2.0)

# 調整後の画像を保存
contrast_img.save('contrast_sample.jpg')

このコードでは、コントラストを2倍に強調しています。コントラストを強めることで、画像の明暗がより際立ち、鮮明な印象を与えることができます。

6.2 ぼかしやシャープ化などのフィルター

Pillowでは、画像にフィルターを適用することも可能です。例えば、画像をぼかす、シャープにするなどの効果を簡単に追加できます。これにはImageFilterモジュールを使用します。

以下は、ぼかしフィルターを適用するコード例です。

from PIL import Image, ImageFilter

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

# ぼかしフィルターを適用
blurred_img = img.filter(ImageFilter.BLUR)

# フィルター適用後の画像を保存
blurred_img.save('blurred_sample.jpg')

このコードでは、ImageFilter.BLURを使用して、画像をぼかしています。同様に、シャープフィルターを適用する場合はImageFilter.SHARPENを使用します。

# シャープフィルターを適用
sharpened_img = img.filter(ImageFilter.SHARPEN)

# フィルター適用後の画像を保存
sharpened_img.save('sharpened_sample.jpg')

このようにして、画像のエッジを強調してシャープ化したり、ソフトな印象にするためにぼかしフィルターを使ったりすることができます。

6.3 特殊フィルターの使用

さらに、Pillowにはいくつかの特殊なフィルターも用意されています。例えば、エッジ検出や輪郭抽出など、画像を分析する際に役立つフィルターもあります。

以下は、エッジ検出フィルターを適用するコード例です。

from PIL import Image, ImageFilter

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

# エッジ検出フィルターを適用
edge_img = img.filter(ImageFilter.FIND_EDGES)

# フィルター適用後の画像を保存
edge_img.save('edge_sample.jpg')

このコードでは、ImageFilter.FIND_EDGESを使用して、画像のエッジ部分だけを強調した画像を作成しています。このようなフィルターは、画像解析やデザインにおいて役立ちます。

7. テキストや図形の描画

7.1 Pillowでテキストを描画する方法

画像にテキストを追加するのは、Pillowを使った画像処理の重要な機能のひとつです。広告バナー、サムネイル、ロゴ画像など、さまざまなデザイン要素にテキストを入れることができます。PillowのImageDrawモジュールを使うと、画像上に自由にテキストを描画することができます。

まず、基本的なテキスト描画の方法を見てみましょう。

from PIL import Image, ImageDraw, ImageFont

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

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

# テキストを描画する
draw.text((10, 10), 'Hello, Pillow!', fill=(255, 255, 255))

# 画像を保存
img.save('text_sample.jpg')

このコードでは、ImageDraw.Draw()で描画用のオブジェクトを作成し、draw.text()メソッドで指定した位置にテキスト「Hello, Pillow!」を描画しています。fillオプションを使って、テキストの色を白(RGB: (255, 255, 255))に設定しています。

7.2 フォントの指定

デフォルトでは、Pillowはシステムの標準フォントを使用しますが、ImageFontモジュールを使うことで、カスタムフォントやサイズを指定することが可能です。以下のコードは、指定したフォントとフォントサイズでテキストを描画する方法です。

from PIL import Image, ImageDraw, ImageFont

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

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

# フォントを指定(TrueTypeフォントを指定)
font = ImageFont.truetype('arial.ttf', 40)

# テキストを描画
draw.text((10, 10), 'Custom Font!', font=font, fill=(255, 255, 255))

# 画像を保存
img.save('font_sample.jpg')

このコードでは、ImageFont.truetype()で指定したフォントファイル(arial.ttf)とフォントサイズ(40)を使ってテキストを描画しています。フォントファイルはシステムにインストールされているものか、手動で追加したものを指定することができます。

7.3 図形の描画

Pillowでは、テキストだけでなく、直線や長方形、円などの図形も簡単に描画できます。これにはImageDrawモジュールのline()rectangle(), ellipse()メソッドを使います。

以下は、画像上に図形を描画するコード例です。

from PIL import Image, ImageDraw

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

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

# 線を描画
draw.line((0, 0, 100, 100), fill=(255, 0, 0), width=5)

# 長方形を描画
draw.rectangle((50, 50, 150, 150), outline=(0, 255, 0), width=3)

# 円(楕円)を描画
draw.ellipse((200, 200, 300, 300), outline=(0, 0, 255), width=3)

# 画像を保存
img.save('shape_sample.jpg')

このコードでは、赤い線、緑の長方形、青い円を画像上に描画しています。line()メソッドでは、座標を指定して線を引き、rectangle()メソッドで長方形、ellipse()メソッドで円や楕円を描画します。outlineオプションで図形の外枠の色、widthオプションで線の太さを指定しています。

7.4 複雑な描画の応用

Pillowでは、複数の図形やテキストを組み合わせて、複雑なデザインを作成することが可能です。例えば、サムネイル画像にタイトルや説明を追加したり、バナー広告に複数のテキストや図形を配置したりすることができます。これにより、ウェブサイトやアプリケーションでのビジュアルコンテンツのカスタマイズが大幅に容易になります。

8. 応用編: 画像の合成やマスク処理

8.1 画像の合成

画像の合成は、複数の画像を組み合わせてひとつの画像を作成するプロセスです。例えば、背景画像の上に別の画像を重ねることで、バナーやコラージュを作成することができます。Pillowでは、paste()メソッドを使って画像を簡単に合成できます。

以下は、画像を合成する基本的なコード例です。

from PIL import Image

# 背景画像と合成する画像を読み込む
background = Image.open('background.jpg')
overlay = Image.open('overlay.png')

# 画像を合成する (位置はx=100, y=100)
background.paste(overlay, (100, 100), overlay)

# 合成した画像を保存
background.save('combined_image.jpg')

このコードでは、background.jpgの上に、overlay.pngを座標(100, 100)に貼り付けています。paste()メソッドの3つ目の引数にoverlay画像を渡すことで、アルファチャネル(透明度)を考慮した合成が可能になります。これにより、透過PNGなどを重ねる際も背景との自然な統合が実現できます。

8.2 マスク画像を使った切り抜き

マスク画像を使用すると、特定の形状に画像を切り抜くことができます。たとえば、円形や星形のような複雑な形状に画像を切り抜いて表示することができます。これには、Pillowのpaste()メソッドとマスク画像を併用します。

以下は、マスク画像を使って円形に切り抜くコード例です。

from PIL import Image, ImageDraw

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

# マスク画像を作成(円形のマスク)
mask = Image.new('L', img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((100, 100, 300, 300), fill=255)

# マスクを適用して画像を貼り付け
result = Image.new('RGB', img.size)
result.paste(img, (0, 0), mask)

# 結果を保存
result.save('masked_image.jpg')

このコードでは、Image.new()でマスク画像を作成し、その上に円形を描画しています。マスク画像の白い部分が可視領域となり、黒い部分が透明として扱われます。その後、paste()メソッドでマスクを適用し、元の画像を貼り付けています。これにより、元の画像が円形に切り抜かれた状態で保存されます。

8.3 アルファチャンネルを使った透過画像の作成

アルファチャンネルを使うことで、部分的に透過した画像を作成することができます。Pillowでは、putalpha()メソッドを使用して画像にアルファチャンネルを追加し、透過度を調整できます。

以下は、アルファチャンネルを追加して透過PNG画像を作成する例です。

from PIL import Image

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

# アルファチャンネルを追加
alpha = img.split()[3]
alpha = alpha.point(lambda p: p * 0.5)  # 透過度50%
img.putalpha(alpha)

# 透過画像を保存
img.save('transparent_image.png')

このコードでは、split()メソッドを使って画像からアルファチャンネルを取り出し、その透過度を50%に変更しています。その後、putalpha()メソッドで画像にアルファチャンネルを再度追加し、透過PNGとして保存しています。

8.4 応用技術でできること

これらの応用技術を使えば、画像編集や合成を自動化したり、ウェブデザインや広告用のバナーを効率的に作成したりすることが可能です。特に、透明度を活かしたロゴの重ね合わせや、特定の部分だけを強調した画像の作成など、多彩な用途に対応できます。Pillowの柔軟な画像処理機能を使うことで、プロジェクトに応じたクリエイティブなビジュアルコンテンツを簡単に生成できます。

9. まとめ

今回の記事では、Pythonの画像処理ライブラリ「Pillow」を使ったさまざまな画像処理技術について詳しく解説しました。Pillowを活用すれば、画像の読み込み、保存、リサイズやトリミングといった基本的な操作から、合成やフィルター適用、テキストや図形の描画まで、幅広い画像操作が非常に簡単に実行できます。

9.1 Pillowの基本操作のおさらい

まず、Pillowのインストールから始め、画像を開いて表示する方法や、画像の基本情報を取得する方法を学びました。これにより、画像処理の基礎を理解し、あらゆる画像に対して柔軟に操作ができるようになったでしょう。

9.2 リサイズやトリミング、回転などの基本的な画像編集

リサイズやトリミング、回転などは画像編集の基本技術です。これらの操作を使うことで、画像のサイズや形を自由に変更し、必要な部分だけを切り抜いたり、方向を調整することができます。これらの操作は、ウェブデザインやアプリケーション開発においても非常に役立ちます。

9.3 フィルターやエフェクトの適用

Pillowを使うと、画像の明るさやコントラストを調整したり、ぼかしやシャープ化、エッジ検出といったフィルターを簡単に適用できます。これにより、画像の質感や印象を大きく変えることができ、プロフェッショナルな画像編集が可能となります。

9.4 テキストや図形の描画、画像の合成

さらに、テキストや図形の描画、複数の画像を合成することで、より高度なデザインが可能です。例えば、バナーやロゴの作成、透過PNG画像の作成など、応用範囲が広がります。特に、マスク処理やアルファチャンネルを使った透過画像の作成は、ウェブやアプリケーションでのデザインにおいて非常に有用です。

9.5 今後の活用に向けて

Pillowの機能はまだまだ奥が深く、公式ドキュメントや他のリソースを活用することで、さらなる応用が可能です。ウェブアプリケーションでの自動画像処理やデータサイエンスプロジェクトでの画像解析、さらには機械学習での画像データ前処理など、さまざまな場面でPillowは重要なツールとなります。

この知識を活かして、今後は自分のプロジェクトでPillowを自由に操り、効率的に画像処理を行っていくことができるでしょう。