Tanuki_Bayashin’s diary

電子工作を趣味としています。最近はラズベリーパイPicoというマイコンを使って楽しんでいます

Pythonにて画像ビューワーを作ってみた~習作~

※なにか気になる点がありましたらコメント欄にご記入ください。

【目次】

1.はじめに

ネットでのサイトであるBOOTHにて、写真集を買いました。画像が全部で40枚ほどありました。

Windows環境なのでエクスプローラで閲覧することもできますが、いまいち見ててしっくりこなかったので、これならと思いPythonにて画像ビューワーを製作しました。

画像1 製作したアプリの画面

簡単に記事として残しておきます。

2.生成物

製作に当たっては、ChatGPTに「こんなソフトが欲しい」という感じで丸投げしたもので、完成度はあまいです。

ソースコードをリスト1に示します。

リスト1

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

class ImageViewer:
    def __init__(self, root):
        self.root = root
        self.root.title("Image Viewer")
        
        self.label = tk.Label(root)
        self.label.pack()

        self.images = []
        self.current_image_index = 0
        self.slide_show_running = False
        
        self.load_button = tk.Button(root, text="Load Images", command=self.load_images)
        self.load_button.pack()
        
        self.next_button = tk.Button(root, text="Next", command=self.show_next_image)
        self.next_button.pack()
        
        self.prev_button = tk.Button(root, text="Previous", command=self.show_previous_image)
        self.prev_button.pack()
        
        self.start_slideshow_button = tk.Button(root, text="Start Slideshow", command=self.start_slideshow)
        self.start_slideshow_button.pack()
        
        self.stop_slideshow_button = tk.Button(root, text="Stop Slideshow", command=self.stop_slideshow)
        self.stop_slideshow_button.pack()

    def load_images(self):
        folder_path = filedialog.askdirectory()
        if folder_path:
            self.images = [os.path.join(folder_path, f) for f in os.listdir(folder_path) if f.endswith(('.png', '.jpg', '.jpeg', '.gif'))]
            if self.images:
                self.current_image_index = 0
                self.show_image()

    def show_image(self):
        if self.images:
            image_path = self.images[self.current_image_index]
            img = Image.open(image_path)
            img = self.resize_image(img, 480, 320)  # 最大サイズを指定
            img_tk = ImageTk.PhotoImage(img)
            self.label.config(image=img_tk)
            self.label.image = img_tk

    def resize_image(self, img, max_width, max_height):
        width, height = img.size
        aspect_ratio = width / height
        
        if width > max_width or height > max_height:
            if aspect_ratio > 1:  # 横長の画像
                new_width = int(max_width * 1.0)
                new_height = int(max_width / aspect_ratio * 1.0)
            else:  # 縦長または正方形の画像
                new_height = int(max_height * 1.0)
                new_width = int(max_height * aspect_ratio * 1.0)

            img = img.resize((new_width, new_height), Image.LANCZOS)
        return img

    def show_next_image(self):
        if self.images:
            self.current_image_index = (self.current_image_index + 1) % len(self.images)
            self.show_image()

    def show_previous_image(self):
        if self.images:
            self.current_image_index = (self.current_image_index - 1) % len(self.images)
            self.show_image()

    def start_slideshow(self):
        if not self.slide_show_running and self.images:
            self.slide_show_running = True
            self.run_slideshow()

    def stop_slideshow(self):
        self.slide_show_running = False

    def run_slideshow(self):
        if self.slide_show_running:
            self.show_next_image()
            self.root.after(20000, self.run_slideshow)  # 2000 ms = 2 seconds

if __name__ == "__main__":
    root = tk.Tk()
    root.geometry("640x480")
    viewer = ImageViewer(root)
    root.mainloop()


インターフェースをGUIとするために、Tkinterを使っています。

仕様としては、

  • 「Load Images」をクリックして、画像が収まっているフォルダーを指定する。(画像は見えてなくていい)
  • 「Next」「Previous」ボタンにて画像を進めたり、戻したりできる
  • 「Start Slideshow」にてスライドショーを開始できる
  • 「Stop Slideshow」にてスライドショーを止められる

といったところです。

コメントは入っていませんが、短いコードなので解読するのにちょうどいいかもしれないです。(自分がめんどくさいだけかも・・)


実際に動かしてみると分かるのですが、Thonnyを用いてプログラムを開始しスライドショーを始めると、コンソール画面にエラーが表示されます。

と言うことで実は未完成です。

改良点はほかにも

  • 「Next」「Previous」などのボタンを、ビデオの操作ボタンのように画像に置き換える
  • スライドショーで現れる画像をランダムに表示させる

などがあげられるでしょう(代り映えしないですが・・)


なにかアイディアが湧いたら、生成AIを用いてコードを作ってもらい、細かい調整を行えば、わりと楽に自分独自のアプリが作れる世の中になってきているのかな、と思ったトピックでした。

ただ、実際にあれこれ生成AIに指示を出してみると、なかなか思い通りのプログラムが出来上がらないことはよくあります。

わざとではなかろうかと思うときもあるくらいです。

生成AIとの付き合いは始まったばかりで、どういう展開を見せるのか見守っていきたいです。

(なんの記事なのかよく分からない・・)

3.まとめ

画像ビューアーのソースコードを張り付け、少しだけ生成AIを用いてソースコードを製作する段取りを記述しました。

生成AIを用いたコーディングの1つの事例みたいになってしまいました。

締まらないですが、これで終わりにします。



最後までお付き合いくださり、ありがとうございました。