Kjetil's Information Center: A Blog About My Projects

Python Image Viewer

Here is Python script I quickly made for browsing through images, and with a button to pass on the filepath of the currently viewed image to another command. However, it's very limited and doesn't even resize images, maybe that and more will be fixed in a future revision.

The code:

#!/usr/bin/python

from Tkinter import *
from PIL import ImageTk, Image
import subprocess
import os.path

class ImageView(Frame):
    def __init__(self, images, command, master=None):
        Frame.__init__(self, master)
        self.grid()
        self._create_widgets()
        self._images = images
        self._command = command
        self._offset = 0
        self._browse(0) # Load first image!

    def _browse(self, offset):
        self._offset += offset
        if self._offset < 0:
            self._offset = 0
        elif self._offset >= len(self._images):
            self._offset = (len(self._images) - 1)

        self.master.title("%s (%d/%d)" % (os.path.basename(self._images[self._offset]), self._offset + 1, len(self._images)))

        self._image_data = ImageTk.PhotoImage(Image.open(self._images[self._offset]))
        self._image = Button(image=self._image_data, bd=0, relief=FLAT, command=lambda: self._browse(1))
        self._image.grid(column=0, row=0, columnspan=7, sticky="news")

    def _exec(self):
        subprocess.call([self._command, self._images[self._offset]])

    def _create_widgets(self):
        self._prev_1   = Button(text="<",   command=lambda: self._browse(-1))
        self._prev_10  = Button(text="<<",  command=lambda: self._browse(-10))
        self._prev_100 = Button(text="<<<", command=lambda: self._browse(-100))
        self._next_1   = Button(text=">",   command=lambda: self._browse(1))
        self._next_10  = Button(text=">>",  command=lambda: self._browse(10))
        self._next_100 = Button(text=">>>", command=lambda: self._browse(100))
        self._exec     = Button(text="Go!", command=self._exec)

        self._prev_100.grid(column=0, row=1, sticky="ew")
        self._prev_10.grid (column=1, row=1, sticky="ew")
        self._prev_1.grid  (column=2, row=1, sticky="ew")
        self._exec.grid    (column=3, row=1, sticky="ew")
        self._next_1.grid  (column=4, row=1, sticky="ew")
        self._next_10.grid (column=5, row=1, sticky="ew")
        self._next_100.grid(column=6, row=1, sticky="ew")

def image_walker(arg, dirname, names):
    for fname in names:
        path = os.path.join(dirname, fname)
        if path.endswith(".jpg"):
            arg.append(path)

if __name__ == "__main__":
    import sys

    if len(sys.argv) < 3:
        print "Usage: %s <image directory> <command>" % (sys.argv[0])
        sys.exit(1)

    images = list()
    os.path.walk(sys.argv[1], image_walker, images)
    if len(images) == 0:
        print "No images found :-("
        sys.exit(1)

    iw = ImageView(sorted(images), sys.argv[2])
    iw.master.resizable(0, 0)
    iw.mainloop()

    sys.exit(0)
          


Topic: Scripts and Code, by Kjetil @ 21/05-2018, Article Link