[PYTHON] Create an image processing viewer with PySimpleGUI

Here's what you can read this article:

image.png

--Viewer to select and display images --Pass parameters for image processing --Display the processed image

For a basic explanation of PySimPleGUI, please refer to If you use Tkinter, try using PySimpleGUI.

Verification environment

Trigger

image.png

I saw the article Automatically generate ASCII art that made the above image, and it was interesting to actually move it. However, since the size of the image and the characters to be ASCII was fixed, I added a UI to that part. The conversion algorithm itself is borrowed from the original article. The asci_art_transform.py file is applicable. The image display itself is based on the official Demo_Img_Viewer. The 08_asci_Img_.py file is applicable.

Where to put the code

It is located on github https://github.com/okajun35/for_pycon_shizu/tree/master/example/08_asci_art

#!/usr/bin/env python
import PySimpleGUI as sg
from PIL import Image, ImageTk
import io
import os

import asci_art_transform as asci

"""
Reference URL; https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Img_Viewer.py
"""

def get_img_data(f, maxsize=(600, 450), first=False):
    """Generate image data using PIL
    """
    print("open file:", f)
    img = Image.open(f)
    img.thumbnail(maxsize)
    if first:  # tkinter is inactive the first time
        bio = io.BytesIO()
        img.save(bio, format="PNG")
        del img
        return bio.getvalue()
    return ImageTk.PhotoImage(img)


filename = './model.jpg'  #First file
asci_image = "./test.png "

image_elem = sg.Image(data=get_img_data(filename, first=True))
filename_display_elem = sg.Text(filename, size=(80, 3))

#It is not necessary to convert to asc at the time of initial display
# './model.jpg'May be angry
# asci_image = tranfa_asci('./model.jpg', './test.png', 16)

asc_image_elem = sg.Image(data=get_img_data(asci_image, first=True))

# define layout, show and read the form
col = [image_elem, asc_image_elem]

col_read_file = [sg.InputText('Select files', key='-INPUT-TEXT-', enable_events=True, ),
                 sg.FileBrowse('Read the file', key='-FILE-',
                               file_types=(('jpeg file', '*.jpg'), ('png', '*.png'),)),
                 sg.Button('conversion')]

layout = [col_read_file,
         [sg.Slider(range=(1,64),
          key='-FONT-SIZE-',
          default_value=16,
         orientation='h',
         )], col]

window = sg.Window('Let's convert it to ASCII art', layout, return_keyboard_events=True,
                   location=(0, 0), use_default_focus=False)

# loop reading the user input and displaying image, filename
i = 0
while True:
    # read the form
    event, values = window.read()
    print(event, values)
    # perform button and keyboard operations
    if event is None:
        break
    elif event == 'conversion':
        print(values['-INPUT-TEXT-'])
        if os.path.isfile(values['-INPUT-TEXT-']):
            #Must be in a separate thread to animate
            sg.popup_animated(sg.DEFAULT_BASE64_LOADING_GIF, message='Running',text_color='black', background_color='white', time_between_frames=100)
            asci_image = asci.tranfa_asci(values['-INPUT-TEXT-'], asci_image, int(values['-FONT-SIZE-']))
            sg.popup_animated(image_source=None)
            print('End of conversion')
            asc_image_elem.update(data=get_img_data(asci_image, first=True))
        else:
            error_massage = values['-INPUT-TEXT-'] + 'Does not exist'
            sg.popup('error', error_massage)

        
    elif values['-FILE-'] != '':
        print('FilesBrowse')
        if os.path.isfile(values['-INPUT-TEXT-']):
            image_elem.update(data=get_img_data(values['-INPUT-TEXT-'], first=True))


About processing

The procedure is as follows.

  1. Open the file dialog and load the file you want to convert
  2. Select the size of the font to convert
  3. Save the converted image to ASCII art
  4. Load the converted image and display it on the result screen

Open the file dialog and load the file you want to convert

sg.InputText('Select files', key='-INPUT-TEXT-', enable_events=True, ),
sg.FileBrowse('Read the file', key='-FILE-',  file_types=(('jpeg file', '*.jpg'), ('png', '*.png'),)

The layout of the file diagnosis.

The initial image is displayed at startup as follows.

image_elem = sg.Image(data=get_img_data(filename, first=True))

filename contains a fixed image file. --Reference: Official Description of Image Element

I'm using get_img_data () to display the image. This method uses the same function used in the official Demo_Img_Viewer.

def get_img_data(f, maxsize=(600, 450), first=False):
    """Generate image data using PIL
    """
    print("open file:", f)
    img = Image.open(f)
    img.thumbnail(maxsize)
    if first:  # tkinter is inactive the first time
        bio = io.BytesIO()
        img.save(bio, format="PNG")
        del img
        return bio.getvalue()
    return ImageTk.PhotoImage(img)

The corresponding file is opened using pillow, and the one saved in png format is displayed using pillow's ʻImage Tk`. --Reference: [ImageTk module description] in the official pillow reference (https://pillow.readthedocs.io/en/4.2.x/reference/ImageTk.html)

PySimpleGUI is a wrapper for tkinter, so I think one of its strengths is that you can use other libraries created like tkinter.

The following part actually displays the read file.

image_elem.update(data=get_img_data(values['-INPUT-TEXT-'], first=True))

The read file is specified. We are now using ʻupdate ()` to update the display.

2. Select the size of the font to convert

Set the size of the font to be converted with the slider

sg.Slider(range=(1,64),
          key='-FONT-SIZE-',
          default_value=16,
         orientation='h',
         )

You can get the slider value below.

event, values = window.read()
values['-INPUT-TEXT-']

3. Save the converted image to ASCII art

The file is read and output to the converted "test.png " file.

asci_image = asci.tranfa_asci(values['-INPUT-TEXT-'], "asci_image", int(values['-FONT-SIZE-']))

4. Load the converted image and display it on the result screen

ASCII art image file "test.png " will be displayed.

asc_image_elem.update(data=get_img_data(asci_image, first=True))

Summary

PySimpleGUI makes it easy to create an image processing viewer that reads an image, adds parameters and converts it. In the official Demo, there are samples using OpenCV other than pillow. There is also a sample program that uses day planning to color black and white images.

Recommended Posts

Create an image processing viewer with PySimpleGUI
Create Image Viewer with Tkinter
Image processing with MyHDL
Image processing with Python
Image Processing with PIL
Create an image composition app with Flask + Pillow
Create an image with characters in python (Japanese)
Image processing with Python (Part 2)
Image processing with PIL (Pillow)
Create an environment with virtualenv
Create an API with Django
Image processing with Python (Part 1)
Image processing with Python (Part 3)
[Python] Image processing with scikit-image
Cut out an image with python
Create an Excel file with Python3
Image processing with Python 100 knocks # 3 Binarization
Create an age group with pandas
Image processing with Python 100 knocks # 2 Grayscale
Try to create an execution path diff viewer with angr + bingraphvis
[Python] I made an image viewer with a simple sorting function.
Basics of binarized image processing with Python
Image processing with Python 100 knock # 10 median filter
Creating an image splitting app with Tkinter
Create a dummy image with Python + PIL.
Image processing with Python 100 knocks # 8 Max pooling
Quickly create an excel file with Python #python
Image processing with Python & OpenCV [Tone Curve]
Image processing with Python 100 knock # 12 motion filter
Create an update screen with Django Updateview
[Python] Quickly create an API with Flask
Drawing with Matrix-Reinventor of Python Image Processing-
Easy image processing in Python with Pillow
Create an add-in-enabled Excel instance with xlwings
[Golang] Create docker image with Github Actions
Create an English word app with python
Image processing with Python 100 knocks # 7 Average pooling
Try to generate an image with aliasing
Light image processing with Python x OpenCV
Image processing with Lambda + OpenCV (gray image creation)
Image processing with Python 100 knocks # 9 Gaussian filter
Create an upgradeable msi file with cx_Freeze
[Image processing] Posterization
XavierNX accelerates OpenCV image processing with GPU (CUDA)
python image processing
Create an app that guesses students with python
Create polka dot wallpaper with Python Image Library
I tried image processing like an event camera
Image processing from scratch with python (5) Fourier transform
How to crop an image with Python + OpenCV
Image processing from scratch with python (4) Contour extraction
Image Processing with Python Environment Setup for Windows
Image processing 100 knocks ①
Rollback processing when an error occurs with fabric
Post an article with an image to WordPress with Python
I tried simple image processing with Google Colaboratory.
Create an API server quickly with Python + Falcon
I want to convert an image to WebP with lollipop
Create an animated GIF local server with Python + Flask
Notes on HDR and RAW image processing with Python
Create an image file using PIL (Python Imaging Library).