Python と Tkinter を使った画像ビューア

PythonBeginner
オンラインで実践に進む

はじめに

このプロジェクトでは、Python と Tkinter を使って画像ビューアアプリケーションを作成します。画像ビューアでは、画像ファイルを開き、表示し、拡大、縮小、画像の回転などの操作を行うことができます。画像操作を処理するために PIL(Python Imaging Library)ライブラリを使い、グラフィカルユーザーインターフェイスを作成するために Tkinter を使います。

👀 プレビュー

画像ビューアアプリケーションのプレビュー

🎯 タスク

このプロジェクトでは、以下のことを学びます。

  • Tkinter を使って GUI アプリケーションを作成する方法。
  • PIL を使って画像の読み込みと表示を処理する方法。
  • 表示された画像に対して拡大、縮小、回転機能を実装する方法。

🏆 成果

このプロジェクトを完了すると、以下のことができるようになります。

  • Python と Tkinter を使って機能的な画像ビューアアプリケーションを開発する。
  • PIL ライブラリを使って画像処理機能を統合する。
  • 拡大と回転などの基本的な画像操作機能を実装する。

プロジェクトファイルを作成する

まず、~/project/image_viewer.py という名前の新しいファイルを作成し、テキストエディタまたは統合開発環境(IDE)で開きます。

cd ~/project
touch image_viewer.py

必要なライブラリをインポートする

image_viewer.py ファイルで、必要なライブラリをインポートします。

import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
from PIL import Image, ImageTk
import os

tkinter ライブラリは GUI 要素を作成する機能を提供し、filedialog を使って画像ファイルを選択するためのファイルダイアログを開くことができ、messagebox はユーザーにメッセージを表示するために使用され、PIL は画像処理に使用され、os はオペレーティングシステムとのやり取りに関する関数を提供します。

ImageViewer クラスを作成する

画像ビューアアプリケーションを処理する ImageViewer という新しいクラスを定義します。

class ImageViewer:
    def __init__(self, root):
        self.root = root
        self.root.title('LabEx Image Viewer')
        self.root.geometry('800x600')
        self.root.configure(background='white')

        self.image_label = tk.Label(self.root)
        self.image_label.pack()

        self.control_frame = tk.Frame(self.root)
        self.control_frame.pack()

        self.open_button = tk.Button(self.control_frame, text='Open', command=self.open_image)
        self.open_button.pack(side='left')

        self.close_button = tk.Button(self.control_frame, text='Quit', command=self.root.quit)
        self.close_button.pack(side='left')

        self.zoom_in_button = tk.Button(self.control_frame, text='Zoom In', command=self.zoom_in)
        self.zoom_in_button.pack(side='left')

        self.zoom_out_button = tk.Button(self.control_frame, text='Zoom Out', command=self.zoom_out)
        self.zoom_out_button.pack(side='left')

        self.rotate_button = tk.Button(self.control_frame, text='Rotate', command=self.rotate)
        self.rotate_button.pack(side='left')

        self.current_image_path = ''
        self.zoom_level = 1

__init__ メソッドでは、タイトル、サイズ、背景色でルートウィンドウを初期化します。その後、画像を表示するためのラベルとコントロールボタン(Open、Quit、Zoom In、Zoom Out、Rotate)を保持するためのフレームを作成します。また、現在の画像パスとズームレベルを追跡するためのインスタンス変数も定義します。

open_image メソッドを実装する

ImageViewer クラスに open_image メソッドを追加します。

    def open_image(self):
        self.current_image_path = filedialog.askopenfilename(defaultextension=".jpg",
            filetypes=[("All Files", "*.*"), ("JPEG", ".jpg"), ("PNG", ".png"), ("GIF", ".gif")])
        if self.current_image_path:
            self.load_image()

open_image メソッドは、画像ファイルを選択するためのファイルダイアログを開きます。選択されたファイルパスに current_image_path 変数を設定し、画像を表示するために load_image メソッドを呼び出します。

load_image メソッドを実装する

load_image メソッドを実装します。

    def load_image(self):
        image = Image.open(self.current_image_path)

        ## Resize image for display
        max_size = (600, 600)
        image.thumbnail(max_size)

        ## Save a reference to the original image (for zooming/rotating)
        self.original_image = image

        ## Create a Tkinter-compatible image
        self.tk_image = ImageTk.PhotoImage(image)
        self.image_label.configure(image=self.tk_image)

        self.zoom_level = 1

load_image メソッドは、PIL の Image.open メソッドを使って選択された画像ファイルを開きます。thumbnail メソッドを使って画像を最大 600x600 ピクセルのサイズにリサイズします。その後、ズームと回転のために元の画像への参照を保存します。次に、ImageTk.PhotoImage を使って Tkinter 互換の画像を作成し、読み込んだ画像を表示するために画像ラベルを更新します。最後に、初期のズームレベルを 1 に設定します。

zoom_in メソッドを実装する

zoom_in メソッドを実装します。

    def zoom_in(self):
        if not self.current_image_path:  ## No image loaded
            return
        self.zoom_level *= 1.1  ## Increase zoom level by 10%
        self.zoom_or_rotate_image()

zoom_in メソッドは画像が読み込まれているかどうかを確認します。画像が読み込まれていない場合は、それ以上処理を行わずに返します。それ以外の場合、ズームレベルを 10%増やし、表示されている画像を更新するために zoom_or_rotate_image メソッドを呼び出します。

zoom_out メソッドを実装する

zoom_out メソッドを実装します。

    def zoom_out(self):
        if not self.current_image_path:  ## No image loaded
            return
        if self.zoom_level < 0.1:  ## Limit outwards zoom
            return
        self.zoom_level *= 0.9  ## Decrease zoom level by 10%
        self.zoom_or_rotate_image()

zoom_out メソッドは画像が読み込まれているかどうかを確認します。画像が読み込まれていない場合は、それ以上処理を行わずに返します。ズームレベルが既に 0.1 未満である場合、つまり画像がズームアウトの限界まで縮小されている場合は、それ以上処理を行わずに返します。それ以外の場合、ズームレベルを 10%減少させ、表示されている画像を更新するために zoom_or_rotate_image メソッドを呼び出します。

rotate メソッドを実装する

rotate メソッドを実装します。

    def rotate(self):
        if not self.current_image_path:  ## No image loaded
            return
        self.original_image = self.original_image.rotate(-90)
        self.zoom_or_rotate_image()

rotate メソッドは画像が読み込まれているかどうかを確認します。画像が読み込まれていない場合は、それ以上処理を行わずに返します。それ以外の場合、PIL の rotate メソッドを使って元の画像を -90 度回転させ、表示されている画像を更新するために zoom_or_rotate_image メソッドを呼び出します。

zoom_or_rotate_image メソッドを実装する

zoom_or_rotate_image メソッドを実装します。

    def zoom_or_rotate_image(self):
        ## Zoom and rotate original image, convert to Tk image, and display
        new_image = self.original_image.resize((int(self.original_image.width * self.zoom_level),
                                                int(self.original_image.height * self.zoom_level)))
        self.tk_image = ImageTk.PhotoImage(new_image)
        self.image_label.configure(image=self.tk_image)

zoom_or_rotate_image メソッドは、現在のズームレベルに基づいて元の画像のサイズを変更します。PIL の resize メソッドを使って更新されたサイズの新しい画像を作成します。その後、ImageTk.PhotoImage を使って新しい画像を Tkinter 互換の画像に変換し、更新された画像を表示するために画像ラベルを更新します。

メインアプリケーションループを作成する

image_viewer.py ファイルの末尾に次のコードを追加して、メインアプリケーションループを作成します。

if __name__ == '__main__':
    root = tk.Tk()
    app = ImageViewer(root)
    root.mainloop()

このコードは、Tkinter のルートウィンドウを作成し、ImageViewer クラスのインスタンスを初期化し、メインアプリケーションループを開始します。

デスクトップに切り替えて、image_viewer.py ファイルを実行してアプリケーションをテストします。次のウィンドウが表示されるはずです。

python image_viewer.py

Tkinter application window

まとめ

おめでとうございます!Python と Tkinter を使って画像ビューアアプリケーションを作成しました。このアプリケーションでは、画像ファイルを開き、表示し、画像を拡大、縮小、回転するなどの操作を行うことができます。画像処理に PIL ライブラリを、グラフィカルユーザーインターフェイスを作成するには Tkinter を使う方法を学びました。さらにアプリケーションをカスタマイズしたり、追加の機能を探求してみることも自由です。

✨ 解答を確認して練習✨ 解答を確認して練習✨ 解答を確認して練習✨ 解答を確認して練習✨ 解答を確認して練習✨ 解答を確認して練習✨ 解答を確認して練習✨ 解答を確認して練習✨ 解答を確認して練習✨ 解答を確認して練習