# -*- coding: utf-8 -*-
##------------------------------------------
## thumbnail library Ver 0.02
## Canvas → Image
##
## 2024.10.22 Masahiro Izutsu
##------------------------------------------
## my_thumbnail.py
##
## Ver 0.02 2024.11.20 ファイルダイアログ エラー対応
# インポート
import os
import copy
import cv2
import numpy as np
import my_videotool
import my_imagetool
import my_movieplay
# 定数定義
THUMB_SIZE = 128
GAP_SIZE = 4
CANVAS_XN = 10
CANVAS_YN = 4
FILE_EXT = ['.jpg', '.JPG', '.png', '.bmp', '.gif', '.mp4']
IMAGE_EXT = ['.jpg', '.JPG', '.png', '.bmp']
MOVIE_EXT = ['.mp4', '.gif']
DEF_THEME = 'GrayGrayGray'
MOVIE_ICON = './movie.png'
MOVIE_ICON_B = './movie_b.png'
AUDIO_ICON = './audio.png'
AUDIO_TEMP = './temp.wav'
# Thumbnail クラス
class Thumbnail:
# 初期化
# self.canvas_xn 横 サムネイル数
# self.canvas_yn 縦 サムネイル数
# self.thunb_size サムネイル ピクセルサイズ
# self.gap_size サムネイル の隙間ピクセル数
# self.file_ext 拡張子のリスト
# self.module_path 実行ディレクトリ
#
def __init__(self, xn = CANVAS_XN, yn = CANVAS_YN, thumb_size = THUMB_SIZE, gap = GAP_SIZE, file_ext = FILE_EXT):
self.canvas_xn = xn
self.canvas_yn = yn
self.thunb_size = thumb_size
self.gap_size = gap
self.file_ext = file_ext
self.module_path = os.path.split(__file__)[0]
self.page_offset = 0
self.page_max = 1
# 初期設定
# self.file_path ファイルパス
# self.file_dir ディレクトリ
# self.files ディレクトリ内のファイルリスト
# self.sel_file 選択ファイル名
# self.images ディレクトリ内のファイル画像リスト
# self.bakimg CANVAS ファイル一覧画像
# self.bak_sel_img CANVAS ファイル一覧画像(選択カーソル付)
# self.filename 一時選択ファイル名
# self.audio_f 音声チェック・フラグ
#
# self.page_max ページの数
# self.page_offset 現在のページ番号 (0~ page_max-1)
#
def initialize(self, file_path, audio_f = False):
self.file_path = file_path
self.audio_f = audio_f
self.files, self.file_dir, self.sel_file = self.get_file_list(file_path, self.file_ext)
if not self.sel_file[-4:] in self.file_ext:
self.sel_file = ''
self.images = self.get_images(self.files, self.file_dir, self.thunb_size, self.gap_size)
self.back_img = self.create_list_image(self.images, self.canvas_xn, self.canvas_yn, self.thunb_size, self.gap_size, self.page_offset)
self.filename = self.sel_file
_, self.bak_sel_img = self.select_file()
self.filename = ''
self.page_max = len(self.files) // (self.canvas_xn * self.canvas_yn) + 1
self.page_offset = 0
return self.bak_sel_img
# CANVAS イメージサイズを得る
def get_canvas_size(self):
return (self.thunb_size * self.canvas_xn + self.gap_size, self.thunb_size * self.canvas_yn + self.gap_size)
# CANVAS イメージを得る(選択カーソル付)
def get_canvas_image(self):
return self.bak_sel_img
# 選択ファイル名を得る
def get_sel_file(self):
return self.sel_file
# 選択ファイルパス名を得る
def get_sel_filepath(self):
return self.file_dir + '/' + self.sel_file
# ページ番号とページの数を得る
def get_page_max(self):
return self.page_offset, self.page_max
# 次のページをチェック
def check_page_up(self):
return self.page_offset + 1 < self.page_max
# 前のページをチェック
def check_page_down(self):
return self.page_offset - 1 >= 0
# 次のページへ
def page_up(self):
image = None
if self.check_page_up():
self.page_offset = self.page_offset + 1
self.back_img = self.create_list_image(self.images, self.canvas_xn, self.canvas_yn, self.thunb_size, self.gap_size, self.page_offset)
self.filename = self.sel_file
_, self.bak_sel_img = self.select_file()
self.filename = ''
return self.bak_sel_img
# 前のページへ
def page_down(self):
image = None
if self.check_page_down():
self.page_offset = self.page_offset - 1
self.back_img = self.create_list_image(self.images, self.canvas_xn, self.canvas_yn, self.thunb_size, self.gap_size, self.page_offset)
self.filename = self.sel_file
_, self.bak_sel_img = self.select_file()
self.filename = ''
return self.bak_sel_img
# CANVAS ピクセル位置からファイル名を得る
# out:
# filename ピクセル位置のファイル名
# image CANVAS ファイル一覧画像(カーソル付)
#
def pixel2file(self, x, y):
self.filename = self.get_image_file(self.files, x, y, self.canvas_xn, self.canvas_yn, self.gap_size, self.thunb_size, self.page_offset, self.page_max)
img = self.set_cursor(self.bak_sel_img, len(self.filename) > 0, x, y, self.canvas_xn, self.canvas_yn, self.gap_size, self.thunb_size)
return self.filename, img
# CANVAS ピクセル位置の画像を選択
# out:
# filename 選択ファイルパス名
# image CANVAS ファイル一覧画像(選択カーソル付)
#
def select_file(self):
if len(self.filename) > 0:
self.sel_file = self.filename
self.bak_sel_img = self.set_select_cursor(self.back_img, self.sel_file, self.files, self.canvas_xn, self.canvas_yn, self.gap_size, self.thunb_size, self.page_offset, self.page_max)
self.file_path = self.file_dir + '/' + self.sel_file
else:
self.bak_sel_img = copy.deepcopy(self.back_img)
return self.file_path, self.bak_sel_img
# ファイル名からパス名を得る
def filename2path(self, filename):
return self.file_dir + '/' + filename
#--------------------------------------------------------------------------^
# ファイルを含むフォルダ内のリストを得る
def get_file_list(self, file_path, file_ext):
if os.path.isdir(file_path): # ディレクトリ指定の場合
file_dir = file_path
sel_file = ''
else: # ファイル指定の場合
base_dir_pair = os.path.split(file_path)
file_dir = base_dir_pair[0]
sel_file = base_dir_pair[1]
files = [
f for f in os.listdir(file_dir) if os.path.isfile(os.path.join(file_dir, f))
]
files = self.check_file_ext(files, file_ext)
files = sorted(files)
return files, file_dir, sel_file
# ファイルのタイプを選別する
def check_file_ext(self, files, file_ext):
chk_files = []
for name in files:
if name[-4:] in file_ext:
chk_files.append(name)
return chk_files
# イメージ一覧を得る (opencv)
def get_images(self, files, file_dir, thunb_size, gap_size, color = (240, 240, 240)):
images = []
for filename in files:
imgfile = os.path.join(file_dir, filename)
img = self.load_image(imgfile, thunb_size, gap_size, color)
images.append(img)
return images
# イメージ画像を得る
def load_image(self, filepath, thunb_size, gap_size, color = (240, 240, 240)):
img = np.zeros((thunb_size, thunb_size, 3), np.uint8)
img[:,:,] = 0xff
name, ext= os.path.splitext(filepath)
if ext == '.jpg' or ext == '.JPG' or ext == '.png' or ext == '.bmp':
img = cv2.imread(filepath)
elif ext == '.mp4' or ext == '.gif':
cap = cv2.VideoCapture(filepath)
if cap.isOpened():
_, img = cap.read()
cap.release()
th_h = thunb_size - gap_size
th_w = thunb_size - gap_size
# 正方形にする
img_h, img_w = img.shape[:2]
if img_h != img_w:
img = my_imagetool.frame_square(img, color)
# 動画マーク表示
if filepath[-4:] == '.mp4' or filepath[-4:] == '.gif':
# 中央に mivie.png を重ねる
if filepath[-4:] == '.gif':
path = MOVIE_ICON_B if self.module_path == '' else self.module_path + MOVIE_ICON_B[1:]
gif_f = True
else:
path = MOVIE_ICON if self.module_path == '' else self.module_path + MOVIE_ICON[1:]
gif_f = False
png_img = cv2.imread(path, cv2.IMREAD_UNCHANGED)
img_h, img_w = img.shape[:2]
w = img_h // 4 if img_h > img_w else img_w // 4
png_img = cv2.resize(png_img, dsize = (w, w))
x0 = img_w // 2 - w // 2
y0 = img_h // 2 - w // 2
x1 = x0 + w
y1 = y0 + w
img[y0:y1, x0:x1] = img[y0:y1, x0:x1] * (1 - png_img[:, :, 3:] / 255) + png_img[:, :, :3] * (png_img[:, :, 3:] /255)
# 右下に audio.png を表示
if self.audio_f and not gif_f:
a_f = my_videotool.mp4_mp3_convert(filepath, AUDIO_TEMP, log_f = False)
if a_f:
path = AUDIO_ICON if self.module_path == '' else self.module_path + AUDIO_ICON[1:]
png_img = cv2.imread(path)
img_h, img_w = img.shape[:2]
w = img_h // 4 - 4 if img_h > img_w else img_w // 4 - 4
png_img = cv2.resize(png_img, dsize = (w, w))
x0 = img_w - w - 4
y0 = img_h - w - 4
x1 = x0 + w
y1 = y0 + w
img[y0:y1, x0:x1] = png_img
if os.path.exists(AUDIO_TEMP):
os.remove(AUDIO_TEMP)
img = cv2.resize(img, dsize = (th_w, th_h))
return img
# ページ内の画像一覧作成 (opencv)
def create_list_image(self, images, canvas_xn, canvas_yn, thunb_size, gap_size, page_offset = 0):
h = thunb_size - gap_size
w = thunb_size - gap_size
frame = np.zeros((thunb_size * canvas_yn, thunb_size * canvas_xn, 3), np.uint8)
frame[:,:,] = 0xff
n = page_offset * canvas_xn * canvas_yn
for yy in range(canvas_yn):
for xx in range(canvas_xn):
if n > len(images) -1:
break
x = xx * thunb_size + gap_size // 2
y = yy * thunb_size + gap_size // 2
frame[y:y + h, x:x + w] = images[n]
n = n + 1
return frame
# マウス座標からイメージファイル名を得る
def get_image_file(self, files, x, y, canvas_xn, canvas_yn, gap_size, thunb_size, page_offset = 0, page_max = 1):
idx = (x - gap_size / 2) // thunb_size
idy = (y - gap_size / 2) // thunb_size
id = int(idy * canvas_xn + idx) + page_offset * canvas_xn * canvas_yn
filename = files[id] if id >= 0 and id < len(files) else ''
return filename
# マウス位置のカーソル表示
def set_cursor(self, image, flg, x, y, canvas_xn, canvas_yn, gap_size, thunb_size):
image2 = copy.deepcopy(image)
x = x - gap_size // 2
y = y - gap_size // 2
x0 = int(((x - gap_size / 2) // thunb_size) * thunb_size + gap_size / 2)
y0 = int(((y - gap_size / 2) // thunb_size) * thunb_size + gap_size / 2)
x1 = int(x0 + thunb_size - gap_size)
y1 = int(y0 + thunb_size - gap_size)
if flg and x0 >= 0 and y0 >=0 and x1 < thunb_size * canvas_yn and y1 < thunb_size * canvas_yn:
cv2.rectangle(image2, (x0, y0), (x1, y1), (0, 0, 0), 1)
return image2
# 選択位置の表示
def set_select_cursor(self, image, filename, files, canvas_xn, canvas_yn, gap_size, thunb_size, page_offset = 0, page_max = 1):
image2 = copy.deepcopy(image)
id = files.index(filename)
if id >= 0 and id >= page_offset * canvas_xn * canvas_yn and id < page_max * canvas_xn * canvas_yn:
id = id - page_offset * canvas_xn * canvas_yn
x = id % canvas_xn
y = id // canvas_xn
x0 = int(x * thunb_size + gap_size / 2)
y0 = int(y * thunb_size + gap_size / 2)
x1 = int(x0 + thunb_size - gap_size)
y1 = int(y0 + thunb_size - gap_size)
cv2.rectangle(image2, (x0, y0), (x1, y1), (255, 0, 0), 2)
return image2
# ファイルタイプを調べる
# out: -1 ファイルがない
# 0 静止画像 (jpg, png, bmp)
# 1 動画 (mp4)
# 2 動画 (gif)
# 3 音声 (wav)
# 9 その他
#
def get_file_type(file_path):
ftype = -1
if os.path.exists(file_path):
ext = file_path[-4:]
if ext == '.jpg' or ext == '.png' or ext == '.bmp':
ftype = 0
elif ext == '.mp4':
ftype = 1
elif ext == '.gif':
ftype = 2
elif ext == '.wav':
ftype = 3
else:
ftype = 9
return ftype
# 静止画選択ダイアログ
#
def image_dialog(file_path, title='', theme='GrayGrayGray', xn=10, yn=4, thumb_size=128, gap=4, file_ext=IMAGE_EXT, ret='', audio_f=False, logger=None):
return file_dialog(file_path, title, theme, xn, yn, thumb_size, gap, file_ext, ret, audio_f, logger)
# 動画選択ダイアログ
#
def movie_dialog(file_path, title='', theme='GrayGrayGray', xn=10, yn=4, thumb_size=128, gap=4, file_ext=MOVIE_EXT, ret='', audio_f=False, logger=None):
return file_dialog(file_path, title, theme, xn, yn, thumb_size, gap, file_ext, ret, audio_f, logger)
# 静止画・動画選択ダイアログ
# in : file_path ファイルパス名
# title タイトルバー表示文字列
# theme PySympliGUI ウインドウのテーマ
# xn 横 サムネイル数
# yn 縦 サムネイル数
# thumb_size サムネイル ピクセルサイズ
# gap サムネイル の隙間ピクセル数
# file_ext 拡張子のリスト
# ret 終了ボタンの文字列 ('' の場合は 'Ok','Cancel' ボタンを表示)
# audio_f 動画の音声再生フラグ
# logger ログ出力オブジェクト
# out : image_file 選択されたファイルパス名 (ret が '' 出ない場合は '')
#
def file_dialog(file_path, title='', theme=DEF_THEME, xn=10, yn=4, thumb_size=128, gap=4, file_ext=FILE_EXT, ret='', audio_f=False, logger=None):
import PySimpleGUI as sg
import tkinter as tk
from PIL import Image, ImageTk
KEY_IMG_SEL = '-ImgSel-'
KEY_TXTIMG = '-TextImg-'
KEY_OK = '-Ok-'
KEY_CANCEL = '-Cancel-'
KEY_PAGE = '-Page-'
KEY_PAGEUP = '-PageUp-'
KEY_PAGEDOWN = '-PageDown-'
# Thumbnail オブジェクト作成
Thumb = Thumbnail(xn, yn, thumb_size, gap, file_ext)
image_file = file_path
frame = Thumb.initialize(image_file, audio_f)
image_file = Thumb.get_sel_filepath()
# ウィンドウのテーマ
sg.theme(theme)
canvas = sg.Image(size = Thumb.get_canvas_size(), key='CANVAS')
# ウィンドウのレイアウト
col_right = [
[sg.Text(image_file, background_color='White', size=(32, 1), key = KEY_IMG_SEL), sg.Text('', size=(32, 1), key = KEY_TXTIMG)],
[canvas],
]
col_btn = [
[
sg.Text("Page: 1/1", size=(12, 1), key=KEY_PAGE),
sg.Button('▼', size=(2, 1), key=KEY_PAGEUP),
sg.Button('▲', size=(2, 1), key=KEY_PAGEDOWN),
sg.Text("", size=(4, 1)),
sg.Button('Ok', size=(8, 1), key=KEY_OK, focus=True),
sg.Button('Cancel', size=(8, 1), key=KEY_CANCEL),
sg.Text("", size=(1, 1))
]
] if ret == '' else [
[
sg.Text("Page: 1/1", size=(12, 1), key=KEY_PAGE),
sg.Button('▼', size=(2, 1), key=KEY_PAGEUP),
sg.Button('▲', size=(2, 1), key=KEY_PAGEDOWN),
sg.Text("", size=(12, 1)),
sg.Button(ret, size=(8, 1), key=KEY_CANCEL, focus=True),
sg.Text("", size=(1, 1))
]
]
layout = [
[sg.Column(col_right, vertical_alignment='top')],
[sg.Column(col_btn, justification='r') ],
]
# ウィンドウオブジェクトの作成
window = sg.Window(title, layout, finalize=True, return_keyboard_events=True, use_default_focus=False)
img = cv2.imencode('.png', frame)[1].tobytes()
window['CANVAS'].update(img)
# ユーザーイベントの定義
canvas.bind('<Motion>', '_motion')
canvas.bind('<ButtonPress>', '_click_on')
canvas.bind('<ButtonRelease>', '_click_off')
canvas.bind('<Double-Button>', '_double_click')
page_offset, page_max = Thumb.get_page_max()
window[KEY_PAGE].update(f'Page: {page_offset + 1}/{page_max}')
window[KEY_PAGEUP].update(disabled = not Thumb.check_page_up())
window[KEY_PAGEDOWN].update(disabled = not Thumb.check_page_down())
if ret == '':
window[KEY_OK].update(disabled = True)
new_make_f = False
# イベントのループ
while True:
event, values = window.read()
if new_make_f:
new_make_f = False
if event == KEY_CANCEL or event == sg.WIN_CLOSED:
image_file = ''
break
if event == KEY_OK:
logger.debug(f'{event} {image_file}')
break
if event == KEY_PAGEUP:
logger.debug(f'{event}')
frame = Thumb.page_up()
if frame is not None:
window[KEY_TXTIMG].update('')
img = cv2.imencode('.png', frame)[1].tobytes()
window['CANVAS'].update(img)
page_offset, page_max = Thumb.get_page_max()
window[KEY_PAGE].update(f'Page: {page_offset + 1}/{page_max}')
window[KEY_PAGEUP].update(disabled = not Thumb.check_page_up())
window[KEY_PAGEDOWN].update(disabled = not Thumb.check_page_down())
if event == KEY_PAGEDOWN:
logger.debug(f'{event}')
frame = Thumb.page_down()
if frame is not None:
window[KEY_TXTIMG].update('')
img = cv2.imencode('.png', frame)[1].tobytes()
window['CANVAS'].update(img)
page_offset, page_max = Thumb.get_page_max()
window[KEY_PAGE].update(f'Page: {page_offset + 1}/{page_max}')
window[KEY_PAGEUP].update(disabled = not Thumb.check_page_up())
window[KEY_PAGEDOWN].update(disabled = not Thumb.check_page_down())
if event == 'CANVAS_motion':
x = canvas.user_bind_event.x
y = canvas.user_bind_event.y
filename, frame = Thumb.pixel2file(x, y)
window[KEY_TXTIMG].update(filename)
img = cv2.imencode('.png', frame)[1].tobytes()
window['CANVAS'].update(img)
if event == 'CANVAS_click_on':
image_file, frame = Thumb.select_file()
window[KEY_IMG_SEL].update(image_file)
img = cv2.imencode('.png', frame)[1].tobytes()
window['CANVAS'].update(img)
logger.debug(f'{event} {image_file}')
if ret == '':
window[KEY_OK].update(disabled = False)
if event == 'CANVAS_click_off':
pass
if event == 'CANVAS_double_click':
ftype = get_file_type(image_file)
if audio_f and ftype == 1:
my_movieplay.movie_play(video_file = image_file, title = image_file)
elif ftype== 0 or ftype == 1 or ftype == 2:
my_imagetool.image2disp(filepath = image_file, winname = image_file, maxsize = 1024)
if ret == '':
window[KEY_OK].update(disabled = False)
# ウィンドウ終了処理
window.close()
return image_file
# フォルダ内のフォルダリストを得る
def get_filder_list(dir_path):
files_dir = [
f for f in os.listdir(dir_path) if os.path.isdir(os.path.join(dir_path, f))
]
files_dir = sorted(files_dir)
return files_dir
# ディレクトリ選択ダイアログ
# in : file_path ディレクトリパス名
# title タイトルバー表示文字列
# theme PySympliGUI ウインドウのテーマ
# xn 横 サムネイル数
# yn 縦 サムネイル数
# thumb_size サムネイル ピクセルサイズ
# gap サムネイル の隙間ピクセル数
# file_ext 拡張子のリスト
# dir_str 検索するディレクトリに含む文字列
# logger ログ出力オブジェクト
# out : dir_path 選択されたファイルパス名 (Cancel の場合は '')
#
def dir_dialog(file_path, title='', theme=DEF_THEME, xn=10, yn=4, thumb_size=128, gap=4, file_ext=[], dir_str='', logger=None):
import PySimpleGUI as sg
import tkinter as tk
from PIL import Image, ImageTk
KEY_IMG_SEL = '-ImgSel-'
KEY_TXTIMG = '-TextImg-'
KEY_DIRLIST = '-DirList-'
KEY_OK = '-Ok-'
KEY_CANCEL = '-Cancel-'
KEY_PAGE = '-Page-'
KEY_PAGEUP = '-PageUp-'
KEY_PAGEDOWN = '-PageDown-'
# Thumbnail オブジェクト作成
Thumb = Thumbnail(xn, yn, thumb_size, gap, file_ext)
image_file = file_path
d_list = get_filder_list(file_path)
dir_list = d_list[:]
if dir_str != '':
for name in d_list:
if not dir_str in name:
dir_list.remove(name)
logger.debug(d_list)
logger.debug(dir_list)
Thumb = []
for folder in dir_list:
Th = Thumbnail(xn, yn, thumb_size, gap, file_ext)
path = file_path + '/' + folder
Th.initialize(path)
Thumb.append(Th)
sel_id = 0
select_dir = file_path + '/' + dir_list[sel_id]
# ウィンドウのテーマ
sg.theme(theme)
canvas = sg.Image(size = Thumb[sel_id].get_canvas_size(), key='CANVAS')
# ウィンドウのレイアウト
col_left = [
[sg.Text("Directory select:", size=(20, 1))],
[sg.Listbox(dir_list, key=KEY_DIRLIST, size = (20, 8), default_values = dir_list[sel_id], enable_events=True)],
]
col_right = [
[canvas],
]
col_btn = [
[
sg.Text("Page: 1/1", size=(12, 1), key=KEY_PAGE),
sg.Button('▼', size=(2, 1), key=KEY_PAGEUP),
sg.Button('▲', size=(2, 1), key=KEY_PAGEDOWN),
sg.Text("", size=(4, 1)),
sg.Button('Ok', size=(8, 1), key=KEY_OK, focus=True),
sg.Button('Cancel', size=(8, 1), key=KEY_CANCEL),
sg.Text("", size=(1, 1))
]
]
layout = [
[sg.Column(col_left, vertical_alignment='top'), sg.Column(col_right, vertical_alignment='top')],
[sg.Column(col_btn, justification='r') ],
]
# ウィンドウオブジェクトの作成
window = sg.Window(title, layout, finalize=True, return_keyboard_events=True)
frame = Thumb[sel_id].get_canvas_image()
img = cv2.imencode('.png', frame)[1].tobytes()
window['CANVAS'].update(img)
page_offset, page_max = Thumb[sel_id].get_page_max()
window[KEY_PAGE].update(f'Page: {page_offset + 1}/{page_max}')
window[KEY_PAGEUP].update(disabled = not Thumb[sel_id].check_page_up())
window[KEY_PAGEDOWN].update(disabled = not Thumb[sel_id].check_page_down())
new_make_f = False
# イベントのループ
while True:
event, values = window.read()
if new_make_f:
new_make_f = False
if event == KEY_CANCEL or event == sg.WIN_CLOSED:
select_dir = ''
break
if event == KEY_OK:
logger.debug(f'{event} {select_dir}')
break
if event == KEY_PAGEUP:
logger.debug(f'{event}')
frame = Thumb[sel_id].page_up()
if frame is not None:
frame = Thumb[sel_id].get_canvas_image()
img = cv2.imencode('.png', frame)[1].tobytes()
window['CANVAS'].update(img)
page_offset, page_max = Thumb[sel_id].get_page_max()
window[KEY_PAGE].update(f'Page: {page_offset + 1}/{page_max}')
window[KEY_PAGEUP].update(disabled = not Thumb[sel_id].check_page_up())
window[KEY_PAGEDOWN].update(disabled = not Thumb[sel_id].check_page_down())
if event == KEY_PAGEDOWN:
logger.debug(f'{event}')
frame = Thumb[sel_id].page_down()
if frame is not None:
frame = Thumb[sel_id].get_canvas_image()
img = cv2.imencode('.png', frame)[1].tobytes()
window['CANVAS'].update(img)
page_offset, page_max = Thumb[sel_id].get_page_max()
window[KEY_PAGE].update(f'Page: {page_offset + 1}/{page_max}')
window[KEY_PAGEUP].update(disabled = not Thumb[sel_id].check_page_up())
window[KEY_PAGEDOWN].update(disabled = not Thumb[sel_id].check_page_down())
if event == KEY_DIRLIST:
d_name = values[KEY_DIRLIST][0]
select_dir = file_path + '/' + d_name
sel_id = dir_list.index(d_name)
frame = Thumb[sel_id].get_canvas_image()
img = cv2.imencode('.png', frame)[1].tobytes()
window['CANVAS'].update(img)
page_offset, page_max = Thumb[sel_id].get_page_max()
window[KEY_PAGE].update(f'Page: {page_offset + 1}/{page_max}')
window[KEY_PAGEUP].update(disabled = not Thumb[sel_id].check_page_up())
window[KEY_PAGEDOWN].update(disabled = not Thumb[sel_id].check_page_down())
logger.debug(select_dir)
# ウィンドウ終了処理
window.close()
return select_dir
# main関数エントリーポイント (テスト))
if __name__ == "__main__":
DEF_IMAGE = './mylib_test/04.jpg'
LOG_LEVEL = 3
import argparse
import my_logging
parser = argparse.ArgumentParser()
parser.add_argument("--source_image", default=DEF_IMAGE, help="path to source image")
parser.add_argument("--cpu", dest="cpu", action="store_true", help="cpu mode.")
parser.add_argument('--log', metavar = 'LOG', default = LOG_LEVEL, help = 'Log level(-1/0/1/2/3/4/5) Default value is \'3\'')
opt = parser.parse_args()
image_file = opt.source_image
title = 'Thumbnail Class Test Ver. 0.01'
# アプリケーション・ログ設定
module = os.path.basename(__file__)
module_name = os.path.splitext(module)[0]
logger = my_logging.get_module_logger_sel(module_name, int(opt.log))
# ディレクトリ選択ダイアログ
file_path = './mylib_test'
dir_str = 'examples'
print(dir_dialog(file_path, title, DEF_THEME, xn=8, yn=3, thumb_size=64, gap=4, file_ext=FILE_EXT, dir_str=dir_str, logger=logger))
# ファイル選択ダイアログ
print(file_dialog(image_file, title, DEF_THEME, CANVAS_XN, CANVAS_YN, THUMB_SIZE, GAP_SIZE, FILE_EXT, audio_f = True, logger=logger))
# イメージ選択ダイアログ
print(image_dialog('./mylib_test/04.jpg', 'Image file select', DEF_THEME, CANVAS_XN, CANVAS_YN, THUMB_SIZE, GAP_SIZE, ret = 'Cancel', logger = logger))
# 動画選択ダイアログ
print(movie_dialog('./mylib_test/2.mp4', 'Movie file select', DEF_THEME, CANVAS_XN, CANVAS_YN, THUMB_SIZE, GAP_SIZE, ret = '', audio_f = True, logger = logger))
logger.info('\nFinished.\n')