Python: Tkinter GUI
Модератор: Olej
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Python: Tkinter GUI
Возникла такая интересная задача... :
- сформированные программами распознавания лиц на Python (см. распознавание лиц) выводить в окна-фреймы-виджеты GUI приложений...
- это должно быть на Python 3 (не Python 2).
P.S. Я по этому поводу даже специальное руководство написал для заказчика ... поскольку это не оговаривалось и не запрещалось - приложу его сюда, может кому-то пригодится.
- сформированные программами распознавания лиц на Python (см. распознавание лиц) выводить в окна-фреймы-виджеты GUI приложений...
- это должно быть на Python 3 (не Python 2).
P.S. Я по этому поводу даже специальное руководство написал для заказчика ... поскольку это не оговаривалось и не запрещалось - приложу его сюда, может кому-то пригодится.
- Вложения
-
- Tkinter_GUI.6.4.odt
- (156.93 КБ) 149 скачиваний
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Python: Tkinter GUI
Вопрос в том, как внутренние форматы хранения изображений пакетов а). numpy (он же - компьютерное зрение OpenCV) и б). Pillow (он же Dlib и OpenFace) подсунуть на вывод графической системе Tcl/Tk через Python3 модуль tkinter? ... а заодно и взаимные преобразования форматов между а). и б).Olej писал(а): - сформированные программами распознавания лиц на Python (см. распознавание лиц) выводить в окна-фреймы-виджеты GUI приложений...
Преобразование форматов (с их отображением) - pil2cv.py:
Код: Выделить всё
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
import numpy
from PIL import Image
import cv2
import dlib
import subprocess
# Take the image file name from the command line
with Image.open( sys.argv[ 1 ] ) as pillow_image:
pillow_image.show()
cv_image = numpy.array( pillow_image )
cv_image = cv2.resize( cv_image, ( 0, 0 ), fx = 0.6, fy = 0.6 )
print( type( cv_image ), cv_image.ndim, cv_image.shape, cv_image.dtype )
print( '[0][0]=>{} , [0][1]=>{}'.
format( cv_image[ 0 ][ 0 ], cv_image[ 0 ][ 1 ] ) )
if cv_image.ndim > 2:
pillow_image = Image.fromarray( cv_image, "RGB" )
else:
pillow_image = Image.fromarray( cv_image, "L" )
pillow_image.show()
print( type( pillow_image ), pillow_image.size, pillow_image.mode )
print( '(0,0)=>{} , (1,0)=>{}'.
format( pillow_image.getpixel( ( 0, 0 ) ), pillow_image.getpixel( ( 1, 0 ) ) ) )
dlib.hit_enter_to_continue()
subprocess.call( [ 'killall', 'display' ] )
- Вложения
-
- pil2cv.py
- (1.86 КБ) 131 скачивание
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Python - графика
Вывод самых разнообразных внешних файлов изображений в фрейм Tcl/Tk - fil2tk.py:Olej писал(а): Преобразование форматов (с их отображением) - pil2cv.py:
Код: Выделить всё
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
import numpy as np
import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
root.geometry( '600x400' )
#root.geometry('600x400+200+100')
#root.resizable( width = False, height = False )
root.title( 'Изображение' )
b1 = tk.Button( root )
b2 = tk.Button( root, text = 'Открыть' )
def showImage():
options = { # define options for opening
'title' : "Choose an image file",
'filetypes' : [ ( "Image", ("*.jpg","*.png","*.gif" ) ),
( "Other", ("*.ppm","*.pgm","*.bmp" ) ),
( "All files", "*.*" ) ]
}
file_name = filedialog.askopenfilename( **options ) # select image file
global b1
b1.destroy()
print( 'image file: {}'.format( file_name ) )
print( root.geometry() )
try: # load image as is ( .jpg, .png, .gif, ... )
tkimg = tk.PhotoImage( file = file_name )
except Exception as err:
print( 'error: {}'.format( err ) )
return
print( type( tkimg ) )
print( tkimg.__str__() )
print( 'height={} width={}'.format( tkimg.height(), tkimg.width() ) )
b1 = tk.Button( root, image = tkimg )
b1.image = tkimg # store a reference to the image as an attribute of the widget
b1.pack( side = 'top' )
return
b2[ 'command' ] = showImage #b.bind( '<Button-1>', showImage )
b2.pack( side='bottom' )
root.mainloop()
Так же точно выглядит выполнение последующих экзамплов.
- Вложения
-
- fil2tk.py
- (2.29 КБ) 114 скачиваний
-
- f1.png (22.35 КБ) 3652 просмотра
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Python - графика
Вывод внутренних представлений изображений масссивами numpy (и OpenCV)...Olej писал(а): Вывод самых разнообразных внешних файлов изображений в фрейм Tcl/Tk - fil2tk.py:
В документации (по tkinter, которая очень скудная) утверждается, что вызов PhotoImage() с ключевым параметром data=… (вместо file=…) создаёт образ изображения для отображения, используя данные уже размещённые в памяти.
Но! Как оказалось, PhotoImage() готов принять, в виде данных, в этом случае не поток сырых байт, а только полный формат представления одного из предусмотренных форматов файлов (с заголовками, «магическими байтами», сжатием для сжимаемых форматов и т. д.).
Для решения этой проблемы (а также для любых пакетов Python и их форматов) нужно сформировать поток байт в памяти, имитирующий простейшие форматы изображений. И здесь нам на помощь приходят так называемые простые форматы изображения PNM (Netpbm format: .pbm, .pgm, .ppm). Мы должны сформировать соответствующий заголовок формата, а далее следующий за ним поток байт собственно изображения (см. Portable anymap).
Приложение cv2tk.py :
Код: Выделить всё
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import numpy as np
import cv2
import tkinter as tk
from tkinter import filedialog
root = tk.Tk() # main frame
root.geometry( '600x400' )
#root.geometry('600x400+200+100')
#root.resizable( width = False, height = False )
root.title( 'Изображение' )
b1 = tk.Button( root ) # image frame
b2 = tk.Button( root, text = 'Открыть' )
def showImage():
options = { # define options for opening
'title' : "Choose an image file",
'filetypes' : [ ( "Image", ("*.jpg","*.png","*.gif" ) ),
( "Other", ("*.ppm","*.pgm","*.bmp" ) ),
( "All files", "*.*" ) ]
}
file_name = filedialog.askopenfilename( **options ) # select image file
global b1
b1.destroy()
print( 'image file: {}'.format( file_name ) )
# print( root.geometry() )
try: # load image as is ( .jpg, .png, .gif, ... )
image = cv2.imread( file_name, cv2.IMREAD_LOAD_GDAL )
if not isinstance( image, np.ndarray ): # to see if reading error occurs
raise Exception ( 'Error format image file', type( image ) )
except Exception as err:
print( 'error: {}'.format( err ) )
return
print( type( image ), image.ndim, image.shape, image.dtype )
print( '[0][0]=>{}'.format( image[ 0 ][ 0 ] ) )
( h, w ) = ( image.shape[ 0 ], image.shape[ 1 ] )
if image.ndim > 2: # if RGB scale
pnm_type = b'P6 '
else: # if gray scale
pnm_type = b'P5 '
head = pnm_type + bytes( str( w ) + ' ' + str( h ) + ' 255 ', 'UTF8' )
# print( head )
xdata = head + image.tobytes()
tkimg = tk.PhotoImage( width = w, height = h, data = xdata, format = 'PPM' )
print( 'height={} width={}'.format( tkimg.height(), tkimg.width() ) )
b1 = tk.Button( root, image = tkimg )
b1.image = tkimg # store a reference to the image as an attribute of the widget
b1.pack( side = 'top' )
return
b2[ 'command' ] = showImage # b.bind( '<Button-1>', showImage )
b2.pack( side='bottom' )
root.mainloop()
- Вложения
-
- cv2tk.py
- (2.36 КБ) 121 скачивание
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Python - графика
Вывод тех же внутренних представлений изображений, но так как это принято в Pillow (PIL).Olej писал(а): Вывод внутренних представлений изображений масссивами numpy (и OpenCV)...
Это, должно быть, проще ... но тут выяснилась сложность, с которой я бодался довольно долго:
В большинстве Linux дистрибутивов, которые я пересмотрел:
Код: Выделить всё
$ python3
Python 3.7.2rc1 (default, Dec 12 2018, 06:25:49)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import PIL
>>> PIL.__version__
'5.3.0'
>>> from PIL import Image
>>> from PIL import ImageTk
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name 'ImageTk'
>>>
Нет там в пакете Pillow модуля ImageTk, который необходим tkinter !
(я не знаю как это выглядит в каком-то говённом Windows, для которого в первую лчередь разрабатывали изначально Pillow/PIL, но в Linux это именно так)
Проблема здесь не в дистрибутиве или версиях (Python и Pillow), а в том, что пакет Pillow в репозиториях PyPI собран с опциями: --dsable-tcl и --disable-tk (как это описывается здесь) — модуля ImageTk нет и он не может быть импортирован. Для того, чтобы исправить ситуацию нужно переустановить Pillow сборкой из исходников - Pillow 5.4.0:
Код: Выделить всё
$ ls -l Pillow*
-rw-r--r-- 1 olej olej 15929265 янв 3 16:36 Pillow-5.4.0.tar.gz
$ tar -zxf Pillow-5.4.0.tar.gz
$ du -hs Pillow-5.4.0
30M Pillow-5.4.0
Код: Выделить всё
$ cd Pillow-5.4.0
$ time sudo python3 setup.py build_ext install
running build_ext
building 'PIL._imaging' extension
creating build
creating build/temp.linux-x86_64-3.7
creating build/temp.linux-x86_64-3.7/src
creating build/temp.linux-x86_64-3.7/src/libImaging
...
Processing Pillow-5.4.0-py3.7-linux-x86_64.egg
Copying Pillow-5.4.0-py3.7-linux-x86_64.egg to /usr/local/lib/python3.7/dist-packages
Adding Pillow 5.4.0 to easy-install.pth file
real 0m17,559s
user 0m15,633s
sys 0m1,710s
Код: Выделить всё
$ python3
Python 3.7.2rc1 (default, Dec 12 2018, 06:25:49)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import PIL
>>> PIL.__version__
'5.4.0'
>>> from PIL import Image
>>> from PIL import ImageTk
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Python - графика
Отображение Pillow форматов - pol2tk.py:Olej писал(а):У нас изменилась версия Pillow, но это не суть важно, важно то, что теперь модуль ImageTk присутствует!
Код: Выделить всё
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageTk
root = tk.Tk() # main frame
root.geometry( '600x400' )
#root.geometry('600x400+200+100')
#root.resizable( width = False, height = False )
root.title( 'Изображение' )
b1 = tk.Button( root ) # image frame
b2 = tk.Button( root, text = 'Открыть' )
def showImage():
options = { # define options for opening
'title' : "Choose an image file",
'filetypes' : [ ( "Image", ("*.jpg","*.png","*.gif" ) ),
( "Other", ("*.ppm","*.pgm","*.bmp" ) ),
( "All files", "*.*" ) ]
}
file_name = filedialog.askopenfilename( **options ) # select image file
global b1
b1.destroy()
print( 'image file: {}'.format( file_name ) )
# print( root.geometry() )
try: # load image as is ( .jpg, .png, .gif, ... )
image = Image.open( file_name )
except Exception as err:
print( 'error: {}'.format( err ) )
return
print( '{} ({}, {})'.format( type( image ),
image.height, image.width, type( image.getpixel( ( 0, 0 ) ) ) ) )
print( '(0,0)=>{}'.format( image.getpixel( ( 0, 0 ) ) ) )
tkimg = ImageTk.PhotoImage( image )
print( 'height={} width={}'.format( tkimg.height(), tkimg.width() ) )
b1 = tk.Button( root, image = tkimg )
b1.image = tkimg # store a reference to the image as an attribute of the widget
b1.pack( side = 'top' )
return
b2[ 'command' ] = showImage # b.bind( '<Button-1>', showImage )
b2.pack( side='bottom' )
root.mainloop()
- Вложения
-
- pil2tk.py
- (1.84 КБ) 126 скачиваний
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Python: Tkinter GUI
Как оказывается, Tkinter очень продуктивный инструмент для быстрой разработки, как и сам Python ... именно для быстрой разработки заметно интереснее, чем альтернативные PyQt или PyGTK.Olej писал(а): Возникла такая интересная задача... :
- сформированные программами распознавания лиц на Python (см. распознавание лиц) выводить в окна-фреймы-виджеты GUI приложений...
- это должно быть на Python 3 (не Python 2).
P.S. Я по этому поводу даже специальное руководство написал для заказчика ... поскольку это не оговаривалось и не запрещалось - приложу его сюда, может кому-то пригодится.
Единственно, по Python + Tkinter документации (по API) в десятки раз меньше, чем по другим инструментам графики.
Поэтому собираем эффективные (не "для чайников") ресурсы по API Tkinter:
tkinter — Python interface to Tcl/Tk - в выпадающем списке там можете выбрать конкретную версию Python для уточнения.
An Introduction to Tkinter (Work in Progress)
Tkinter 8.5 reference: a GUI for Python
Курс по библиотеке Tkinter языка Python
Если эти страницы открыть в браузере на время написания Python/Tkinter кода, то этого, кажется, вполне достаточно в качестве онлай-справки для написания кода.
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Python - графика
Продолжение задачи...Olej писал(а):Возникла такая интересная задача... :
- нужно из видеопотока нарезать отдельные изображения лиц, для заполнения каталога эталонных изображений в распознавании лиц...
- видеопотоком может быть, на выбор, альтернативно: а). WEB камера, одна из нескольких на выбор, б). записанный видеофайл .avi/.mkv, в). каталог с линейным набором файлов-картинок .jpg/.png/.gif/.ppm/.pgm/.bmp ...
- нужно простое и быстрое в работе приложение для таких целей.
Код: Выделить всё
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageTk
import threading
import numpy as np
import sys, os, time, argparse
from common import *
parser = argparse.ArgumentParser() # construct the argument parse and parse the arguments
parser.add_argument( '-i', '--image', required = False, help = 'video stream source' )
parser.add_argument( '-k', '--known', required = False, help = 'known persons directory' )
parser.add_argument( '-v', '--verbose', action = 'count', help = 'increase output verbosity' )
args = vars( parser.parse_args() )
debug = set_debug( args[ 'verbose' ] ) # verbose level
if debug > 1: print( args )
if debug: print( get_version() )
dir_name = './' # known faces directory
if args[ 'known' ] != None:
dir_name = args[ 'known' ]
if not os.path.isdir( dir_name ):
print( 'illegal directory: '.format( dir_name ) )
sys.exit( 1 )
root = tk.Tk() # main frame
root.geometry( '640x480+200+100' )
root.resizable( width = False, height = False )
root.title( 'Select images, ' + get_version() )
c1 = tk.Canvas( root )
lock = threading.Semaphore()
finish = False # quit flag
image = None
def runImage():
global lock, finish, image
sourcer = get_source( args[ 'image' ] ) # get images sourcer
first = True
try: # while exit...
while not finish:
lock.acquire()
ret, frame, delay = sourcer() # grab a single frame
lock.release()
if not ret: break # end of stream
if not isinstance( frame, np.ndarray ): # wrong format file
continue
if finish: break
if 2 == frame.ndim: # gray scale to BGR
frame = cv2.cvtColor( frame, cv2.COLOR_GRAY2BGR )
if first and debug > 0:
height = np.size( frame, 0 ); width = np.size( frame, 1 )
print( 'OpenCV: w={} , h={}'.format( width, height ) )
frame = cv2.cvtColor( frame, cv2.COLOR_BGR2RGB ) # convert from BGR to RGB
image = Image.fromarray( frame, 'RGB' ) # PIL image
if finish: break
if first and debug > 0:
height = image.height; width = image.width
print( 'PIL: w={} , h={}'.format( width, height ) )
tkimg = ImageTk.PhotoImage( image ) # Tk image
if finish: break
if first and debug > 0:
print( 'PhotoImage: w={} , h={}'.format( tkimg.width(), tkimg.height() ) )
c1.winfo_toplevel().geometry( '{}x{}+200+100'.format( tkimg.width(), tkimg.height() + 50 ) )
if finish: break
c1.create_image( tkimg.width() / 2, tkimg.height() / 2, image = tkimg )
c1.pack( side = 'top', fill = 'both', expand = True )
if finish: break
time.sleep( delay / 1000. )
first = False
except ( AttributeError, RuntimeError, KeyboardInterrupt, Exception ) as error:
lock.release()
if debug > 1: print( 'thread function exception' )
return
else:
if debug > 1: print( 'thread function break' )
return
def on_delete():
global dir_name
options = { # define options for deleting
'title' : 'Delete image file',
'filetypes' : [ ( "Image", ("*.jpg","*.png","*.gif" ) ),
( "Other", ("*.ppm","*.pgm","*.bmp" ) ),
( "All files", "*.*" ) ],
}
title = filedialog.askopenfilename( **options )
if 0 == len( title ): return # cancel
n = title.rfind( os.sep )
dir_name = title[ 0:n ]
os.remove( title )
b2 = tk.Button( root, text = 'Delete image' )
b2.pack( side = 'bottom' )
b2[ 'command' ] = on_delete # b2.bind( '<Button-1>', on_delete )
file_name = '.jpg'
def on_save():
global file_name, dir_name, lock
lock.acquire()
options = { # define options for saving
'title' : 'Save image as file...',
'filetypes' : [ ( "Image", ("*.jpg","*.png","*.gif" ) ),
( "Other", ("*.ppm","*.pgm","*.bmp" ) ),
( "All files", "*.*" ) ],
'initialfile' : file_name,
'initialdir' : dir_name
}
title = filedialog.asksaveasfilename( **options ) # select image file
if 0 == len( title ): # cancel
lock.release()
return
n = title.rfind( os.sep )
dir_name, file_name = title[ 0:n ], title[ n + 1: ]
if debug > 1: print( '{} => {} | {}'.format( title, dir_name, file_name ) )
try:
image.save( title )
except ( ValueError, Exception ) as error:
print( "error: image file can't save: {}!".format( error ) )
lock.release()
b1 = tk.Button( root, text = ' Save as... ' )
b1.pack( side = 'bottom' )
b1[ 'command' ] = on_save # b1.bind( '<Button-1>', on_save )
sys.setswitchinterval( 1 )
thread = threading.Thread( target = runImage )
thread.start() # visualisation video ...
def on_closing(): # exit application
global finish
print( ' ... waiting ...' )
lock.acquire()
t1 = time.strftime( '%H:%M:%S' )
finish = True
root.destroy()
thread.join( timeout = 3 )
t2 = time.strftime( '%H:%M:%S' )
if debug > 1:
print( '{} ... {} - thread is running: {}'.format( t1, t2, thread.is_alive() ) )
if( thread.is_alive() ):
raise KeyboardInterrupt( 'thread not finished: press ^C' )
lock.release()
sys.exit()
def on_closing1():
lock.acquire()
on_closing()
root.protocol( 'WM_DELETE_WINDOW', on_closing ) # winclose interrupt
root.bind( '<Escape>', lambda e: on_closing() ) # Esc interrupt
try:
root.mainloop()
except KeyboardInterrupt: # ^C interrupt
if debug > 1: print( '\n***************' )
on_closing()
Код: Выделить всё
olej@ACER:~/2019_WORK/own.WORK/AplitSoft/FaceDL/fred$ ./fred.py -h
usage: fred.py [-h] [-i IMAGE] [-k KNOWN] [-v]
optional arguments:
-h, --help show this help message and exit
-i IMAGE, --image IMAGE
video stream source
-k KNOWN, --known KNOWN
known persons directory
-v, --verbose increase output verbosity
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Python: Tkinter GUI
Единственно нехорошая особенность этого кода - он написан в императивном, структурном стиле + пришлось чередовать операторы главной ветви программы и описания используемых функций ... об этом я зафиксировал даже в отдельной теме: Python: предварительное определение функций. Потом, позже, работать с модификацией такого кода будет сплошным гемороем.Olej писал(а): Продолжение задачи...
Выход - переписать это в объектном стиле:
Код: Выделить всё
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageTk
import threading
import numpy as np
import sys, os, time, argparse
from common import *
parser = argparse.ArgumentParser() # construct the argument parse
parser.add_argument( '-i', '--image', required = False, help = 'video stream source' )
parser.add_argument( '-k', '--known', required = False, help = 'known persons directory' )
parser.add_argument( '-v', '--verbose', action = 'count', help = 'increase output verbosity' )
args = vars( parser.parse_args() )
debug = set_debug( args[ 'verbose' ] ) # verbose level
if debug: print( '{}, verbose level {}'.format( get_version(), debug ) )
class Application( tk.Frame ):
global debug
dir_name = './' # known faces directory
file_name = '.jpg' # last image name
lock = threading.Semaphore()
finish = False # finish thread flag
image = None; thread = None
def __init__( self, args ):
if debug > 1: print( args )
if args[ 'known' ] != None:
dir_name = args[ 'known' ]
if not os.path.isdir( dir_name ):
print( 'illegal directory: '.format( dir_name ) )
sys.exit( 1 )
tk.Frame.__init__( self, master = None )
root = self.winfo_toplevel() # main window
root.protocol( 'WM_DELETE_WINDOW', self.on_closing ) # winclose interrupt
root.bind( '<Escape>', lambda e: self.on_closing() ) # Esc interrupt
root.geometry( '640x480+200+100' )
root.resizable( width = False, height = False )
root.title( 'Select images, ' + get_version() )
root.config( padx = 10, pady = 10 )
self.pack()
sys.setswitchinterval( 1 )
self.thread = threading.Thread( target = self.runImage )
self.thread.start() # visualisation video ...
self.c1 = tk.Canvas( self ) # canvas for image
if debug > 2: print( 'Canvas: {}'.format( self.c1.keys() ) )
self.b1 = tk.Button( self, text = 'Delete image' )
if debug > 2: print( 'Button: {}'.format( self.b1.keys() ) )
self.b1[ 'command' ] = self.on_delete
self.b1.pack( side = 'bottom' )
self.b2 = tk.Button( self, text = ' Save as... ' )
self.b2[ 'command' ] = self.on_save
self.b2.pack( side = 'bottom' )
def on_delete( self ):
self.b1.config( relief = tk.SUNKEN )
options = { # define options for deleting
'title' : 'Delete image file',
'filetypes' : [ ( "Image", ("*.jpg","*.png","*.gif" ) ),
( "Other", ("*.ppm","*.pgm","*.bmp" ) ),
( "All files", "*.*" ) ],
}
title = filedialog.askopenfilename( **options )
if len( title ) != 0:
n = title.rfind( os.sep )
self.dir_name, file_name = title[ 0:n ], title[ n + 1: ]
os.remove( title )
if debug > 0:
print( 'file {} delete from directory {}'.format( file_name, self.dir_name ) )
self.b1.config( relief = tk.RAISED )
def on_save( self ):
self.b2.config( relief = tk.SUNKEN )
self.lock.acquire()
options = { # define options for saving
'title' : 'Save image as file...',
'filetypes' : [ ( "Image", ("*.jpg","*.png","*.gif" ) ),
( "Other", ("*.ppm","*.pgm","*.bmp" ) ),
( "All files", "*.*" ) ],
'initialfile' : self.file_name,
'initialdir' : self.dir_name
}
title = filedialog.asksaveasfilename( **options ) # select image file
if len( title ) != 0: # cancel
n = title.rfind( os.sep )
self.dir_name, self.file_name = title[ 0:n ], title[ n + 1: ]
if debug > 1:
print( '{} => {} | {}'.format( title, self.dir_name, self.file_name ) )
try:
self.image.save( title )
except ( ValueError, Exception ) as error:
print( "error: image file can't save: {}!".format( error ) )
else:
if debug > 0:
print( 'file {} add to directory {}'.format( self.file_name, self.dir_name ) )
self.lock.release()
self.b2.config( relief = tk.RAISED )
def on_closing( self ): # exit application
print( ' ... waiting ...' )
self.lock.acquire()
t1 = time.strftime( '%H:%M:%S' )
self.finish = True
self.winfo_toplevel().destroy()
self.thread.join( timeout = 3 )
t2 = time.strftime( '%H:%M:%S' )
if debug > 1:
print( '{} ... {} - thread is running: {}'.format( t1, t2, self.thread.is_alive() ) )
if( self.thread.is_alive() ):
raise KeyboardInterrupt( 'thread not finished: press ^C' )
self.lock.release()
self.quit()
def runImage( self ):
sourcer = get_source( args[ 'image' ] ) # get images sourcer
first = True
try:
while not self.finish: # while not exit...
self.lock.acquire()
ret, frame, delay = sourcer() # grab a single frame
self.lock.release()
if not ret: break # end of stream
if not isinstance( frame, np.ndarray ): # wrong format file
continue
if self.finish: break
if 2 == frame.ndim: # gray scale to BGR
frame = cv2.cvtColor( frame, cv2.COLOR_GRAY2BGR )
if first and debug > 1:
height = np.size( frame, 0 ); width = np.size( frame, 1 )
print( 'OpenCV: w={} , h={}'.format( width, height ) )
frame = cv2.cvtColor( frame, cv2.COLOR_BGR2RGB ) # convert from BGR to RGB
self.image = Image.fromarray( frame, 'RGB' ) # PIL image
if self.finish: break
if first and debug > 1:
height = self.image.height; width = self.image.width
print( 'PIL: w={} , h={}'.format( width, height ) )
tkimg = ImageTk.PhotoImage( self.image ) # Tk image
if self.finish: break
if first and debug > 1:
print( 'PhotoImage: w={} , h={}'.format( tkimg.width(), tkimg.height() ) )
self.c1.winfo_toplevel().geometry( '{}x{}+200+100'.format( tkimg.width(), tkimg.height() + 70 ) )
self.c1.configure( width = tkimg.width(), height = tkimg.height() )
if self.finish: break
self.c1.create_image( tkimg.width() / 2, tkimg.height() / 2, image = tkimg )
self.c1.pack( side = 'top', fill = 'both', expand = True )
if self.finish: break
time.sleep( delay / 1000. )
first = False
except ( AttributeError, RuntimeError, KeyboardInterrupt, Exception ): # as error:
self.lock.release()
if debug > 1: print( 'thread function exception' )
return
else:
if debug > 1: print( 'thread function break' )
return
app = Application( args )
try:
app.mainloop()
except KeyboardInterrupt: # ^C interrupt
if debug > 1: print( '\n*************** ^C' )
app.on_closing()
- Вложения
-
- fredo.py
- (8.36 КБ) 110 скачиваний
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: Python - графика
Как видно, это такое минимальное творение... Разархивируем куда-нибудь (в $HOME):Olej писал(а): Скачивается здесь (Linux): http://www.bitflipper.ca/rapyd/rapyd-1-0-2.tgzКод: Выделить всё
olej@ACER:~/Загрузки$ ls -l rapyd-1-0-2.tgz -rw-r--r-- 1 olej olej 624203 фев 2 14:10 rapyd-1-0-2.tgz
Код: Выделить всё
olej@ACER:~$ ls -l rapyd-1-0-2
итого 2448
-rw-r--r-- 1 olej olej 32603 июл 1 2014 dnd_realworld.py
-rw-r--r-- 1 olej olej 25751 фев 2 14:16 dnd_realworld.pyc
drwxr-xr-x 2 olej olej 4096 фев 2 14:13 Icons
-rw-r--r-- 1 olej olej 63263 июл 1 2014 rapyd.config
-rw-rw-r-- 1 olej olej 21048 июл 1 2014 RapydDemo.rpj
-rw-rw-r-- 1 olej olej 587514 июл 1 2014 rapyd.help
-rwxr-xr-x 1 olej olej 701951 июл 1 2014 rapyd.py
-rw-r--r-- 1 olej olej 2166 июл 1 2014 rapyd.template
-rw-r--r-- 1 olej olej 4554 июл 1 2014 README.TXT
-rw-r--r-- 1 olej olej 26685 июл 1 2014 rpErrorHandler.py
-rw-r--r-- 1 olej olej 18501 фев 2 14:16 rpErrorHandler.pyc
-rw-r--r-- 1 olej olej 196658 июл 1 2014 rpHelp.py
-rw-r--r-- 1 olej olej 141548 фев 2 14:16 rpHelp.pyc
-rw-rw-r-- 1 olej olej 143436 июл 1 2014 rpOption.py
-rw-r--r-- 1 olej olej 115862 фев 2 14:16 rpOption.pyc
-rw-r--r-- 1 olej olej 215769 июл 1 2014 rpWidgets.py
-rw-r--r-- 1 olej olej 151311 фев 2 14:16 rpWidgets.pyc
-rw-r--r-- 1 olej olej 13402 июл 1 2014 versions.txt
-rw-r--r-- 1 olej olej 0 фев 2 14:20 xlocker.dec
Запуск непосредственно из разархивированного каталога:
Код: Выделить всё
olej@ACER:~/rapyd-1-0-2$ ./rapyd.py
...
- Вложения
-
- r0.png
- (22.67 КБ) 1649 скачиваний
-
- r1.png (30.2 КБ) 3538 просмотров
-
- r2.png (12.88 КБ) 3538 просмотров
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей