DEV Community

Cover image for The Picture Application with Python and TKinter
Deotyma
Deotyma

Posted on

9 1

The Picture Application with Python and TKinter

A few days ago I tested how Pillow works with Python and I liked so I decided to write a little application with Pillow and Tkinter.

Here there are explications of how I started a project.

In a project, I create a file pillow_essaies.py where I put all code from main.py.

In main.py I start my project:

import tkinter as tk
from tkinter import *

window = Tk()
window.title("Pictures transformer")
window.geometry("900x500+100+100")
window.configure(bg="#e2f9b8")

window.mainloop()
Enter fullscreen mode Exit fullscreen mode

first image

I add also an icon, for this, I have to import Pillow:

from PIL import Image, ImageTk
Enter fullscreen mode Exit fullscreen mode

and I create an icon:

# icon
image_icon=ImageTk.PhotoImage(file="images/tulips.jpeg")
window.iconphoto(False, image_icon)
Enter fullscreen mode Exit fullscreen mode

icon od tulips

One icon is added now I add an image to the interface. The order is very important because of ImageTk.PhotoImage has no method resize :

# logo
image = Image.open("./images/tulips.jpeg")
img1 = image.resize((70, 100), Image.ANTIALIAS)
logo = ImageTk.PhotoImage(img1)
Label(image=logo, bg="#fff").place(x=10, y=10)
Enter fullscreen mode Exit fullscreen mode

interface with logo

I add also some text:

Label(text="Pictures transformer", font="arial 30 bold", fg="#313715", bg="#e2f9b8").place(x=90, y=50)
Enter fullscreen mode Exit fullscreen mode

text added

Now I create a space where I will import an image:

# selected image
selectimage = Frame(width=400, height=400, bg="#d6dee5")
selectimage.place(x=10, y=120)

f = Frame(selectimage, bg="black", width=380, height=320)
f.place(x=10, y=10)

lbl = Label(f, bg="black)
lbl.place(x=0, y=0)
Enter fullscreen mode Exit fullscreen mode

section image

Now I need to import an image from the computer. For this I create a button:

Button(selectimage, text="Select image", width=12, height=2, font="arial 14 bold", command=showimage).place(x=10, y=340)
Enter fullscreen mode Exit fullscreen mode

I need to write a function showimage. For this I import os and filedialog:

from tkinter import filedialog
import os
Enter fullscreen mode Exit fullscreen mode
def showimage():
    filename=filedialog.askopenfilename(initialdir=os.getcwd(),
                                        title="Select image file", filetypes=(("PNG file", "*.png"),
                                                                              ("JPG file", "*.jpg"),
                                                                              ("JPEG file", "*.jpeg"),
                                                                              ("ALL file", "*.txt")))
    importedimage = Image.open(filename)
    importedimage = ImageTk.PhotoImage(importedimage)
    lbl.configure(image=importedimage, width=380, height=320)
    lbl.image=importedimage
Enter fullscreen mode Exit fullscreen mode

Image impoeted

Here I will add some filters. I start with buttons:

# transformation section
transformationsection = Frame(width=440, height=510, bg="#939f5c")
transformationsection.place(x=450, y=10)

Label(transformationsection, text="Filters:", font="arial 20 bold", fg="#fff", bg="#939f5c").place(x=10, y=10)

Button(transformationsection, text="BLUR", width=12, height=2, font="arial 14 bold", command=blurimage).place(x=10,
                                                                                                              y=50)
Button(transformationsection, text="CONTOUR", width=12, height=2, font="arial 14 bold", command=conturimage).place(x=155, y=50)
Button(transformationsection, text="EMBOSS", width=12, height=2, font="arial 14 bold", command=embossimage).place(x=300, y=50)
Enter fullscreen mode Exit fullscreen mode

Here I create some functions:

def blurimage():
    image1 = Image.open(filename)
    bluredimage = image1.filter(ImageFilter.BLUR)
    bluredimage = ImageTk.PhotoImage(bluredimage)
    lbl.configure(image=bluredimage, width=380, height=320)
    lbl.image = bluredimage
Enter fullscreen mode Exit fullscreen mode

But a function like this will not work because filename is not yet a global variable and from PIL I don't yet import ImageFilter so I do it like this:

from PIL import ImageFilter
Enter fullscreen mode Exit fullscreen mode

and I define in function showimage filename like glonal:

 global filename
    filename = filedialog.askopenfilename(initialdir=os.getcwd(),
                                          title="Select image file", filetypes=(("PNG file", "*.png"),
                                                                                ("JPG file", "*.jpg"),
                                                                                ("JPEG file", "*.jpeg"),
                                                                                ("ALL file", "*.txt")))
Enter fullscreen mode Exit fullscreen mode

And now it works:

Blur image

Other functions are very easy to create:

def conturimage():
    image2 = Image.open(filename)
    conturedimage = image2.filter(ImageFilter.CONTOUR)
    conturedimage = ImageTk.PhotoImage(conturedimage)
    lbl.configure(image=conturedimage, width=380, height=320)
    lbl.image = conturedimage

def embossimage():
    image3 = Image.open(filename)
    embossedimage = image3.filter(ImageFilter.EMBOSS)
    embossedimage = ImageTk.PhotoImage(embossedimage)
    lbl.configure(image=embossedimage, width=380, height=320)
    lbl.image = embossedimage
Enter fullscreen mode Exit fullscreen mode

Filter CONTOUR
contour image

Filter EMBOSS

Image embossed

That's good, but what if I want to suppress all changes?
So in the section selected image, I create a button to restart:

Button(selectimage, text="Restart", width=12, height=2, font="arial 14 bold", command=restartimage).place(x=260, y=340)
Enter fullscreen mode Exit fullscreen mode

And here is its function:

def restartimage():
    restartedimage = Image.open(filename)
    restartedimage = ImageTk.PhotoImage(restartedimage)
    lbl.configure(image=restartedimage, width=380, height=320)
    lbl.image = restartedimage  
Enter fullscreen mode Exit fullscreen mode

but more efficace will be that function:

def restartimage():
    lbl.configure(image=importedimage, width=380, height=320)
    lbl.image = importedimage
Enter fullscreen mode Exit fullscreen mode

restarted image

Now I would like to rotate my picture so I create a slider:

# rotate section
Label(transformationsection, text="Rotate image:", font="arial 20 bold", fg="#fff", bg="#939f5c").place(x=10, y=100)

rotateimage = Scale(transformationsection, from_=0, to=360, orient=HORIZONTAL, bg="#313715", length=420)
rotateimage.place(x=10, y=140)
Enter fullscreen mode Exit fullscreen mode

slider rotation image

and function which goes with it:

def rotate(var):
    image4 = Image.open(filename)
    rotatedimage = image4.rotate(rotateimage.get())
    rotatedimage = ImageTk.PhotoImage(rotatedimage)
    lbl.configure(image=rotatedimage, width=380, height=320)
    lbl.image = rotatedimage
Enter fullscreen mode Exit fullscreen mode

rotated image

Now I want to change some colors so I create a vertical slider for each color:

# color change
Label(transformationsection, text="Color change:", font="arial 20 bold", fg="#fff", bg="#939f5c").place(x=10, y=190)

redimage = Scale(transformationsection, from_=0, to=255, orient=VERTICAL, bg="#313715", length=180, command=changered)
redimage.place(x=40, y=230)
Label(transformationsection, text="RED", font="arial 12 bold", fg="#fff", bg="#939f5c").place(x=40, y=420)

greenimage = Scale(transformationsection, from_=0, to=255, orient=VERTICAL, bg="#313715", length=180, command=changegreen)
greenimage.place(x=200, y=230)
Label(transformationsection, text="GREEN", font="arial 12 bold", fg="#fff", bg="#939f5c").place(x=200, y=420)

blueimage = Scale(transformationsection, from_=0, to=255, orient=VERTICAL, bg="#313715", length=180,  command=changeblue)
blueimage.place(x=350, y=230)
Label(transformationsection, text="BLUE", font="arial 12 bold", fg="#fff", bg="#939f5c").place(x=350, y=420)
Enter fullscreen mode Exit fullscreen mode

And I create some functions to change colors:

def changered(var):
    image5 = Image.open(filename)
    r, g, b = image5.split()
    r = r.point(lambda i: redimage.get())
    coloredimage = Image.merge("RGB", (r, g, b))
    coloredimage.getextrema()
    coloredimage = ImageTk.PhotoImage(coloredimage)
    lbl.configure(image=coloredimage, width=380, height=320)
    lbl.image = coloredimage

def changeblue(var):
    image5 = Image.open(filename)
    r, g, b = image5.split()
    b = b.point(lambda i: blueimage.get())
    coloredimage = Image.merge("RGB", (r, g, b))
    coloredimage.getextrema()
    coloredimage = ImageTk.PhotoImage(coloredimage)
    lbl.configure(image=coloredimage, width=380, height=320)
    lbl.image = coloredimage

def changegreen(var):
    image5 = Image.open(filename)
    r, g, b = image5.split()
    g = g.point(lambda i: greenimage.get())
    coloredimage = Image.merge("RGB", (r, g, b))
    coloredimage.getextrema()
    coloredimage = ImageTk.PhotoImage(coloredimage)
    lbl.configure(image=coloredimage, width=380, height=320)
    lbl.image = coloredimage
Enter fullscreen mode Exit fullscreen mode

Voilà the result:

colors changed image

All code of this little application you can find here

This is an example of how you can use the Pillow and Tkinter.
Have a nice weekend and get some rest.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

The Most Contextual AI Development Assistant

Pieces.app image

Our centralized storage agent works on-device, unifying various developer tools to proactively capture and enrich useful materials, streamline collaboration, and solve complex problems through a contextual understanding of your unique workflow.

👥 Ideal for solo developers, teams, and cross-company projects

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay