python PIL and tkinter; brightening image and displaying it - python

What I want to be able to do is open a window with two images (one image is an exact copy of the other). Then when I click a button it changes the image on the right. I hope this is making sense. The code I have no is:
from __future__ import division
from Tkinter import *
from PIL import Image, ImageTk, ImageFilter
import random
class MyApp(object):
def __init__(self):
self.root = Tk()
self.root.wm_title("Image examples")
img = Image.open("lineage.jpg").convert("RGB")
(w, h) = (img.size[0], img.size[1])
print (w, h)
tkpi = ImageTk.PhotoImage(img)
label = Label(self.root, image=tkpi)
label.grid(row=0, column=0, padx=5, pady=5, rowspan=10)
img2 = img.copy()
pixels = img2.load()
tkpi2 = ImageTk.PhotoImage(img2)
label = Label(self.root, image=tkpi2)
label.grid(row=0, column=1, padx=5, pady=5, rowspan=10)
Button(self.root, text="Brighten", command=self.brighten).grid(row=0, column= 2)
self.root.mainloop()
def brighten(self):
self.pixels = self.pixels.point(lambda x: x*1.9)
MyApp()
What I am trying to is have img2 update when I click on the brighten button. When I try now I get this error:
File "C:\Users\Admin\Desktop\imageeditor.py", line 36, in brighten
self.pixels = self.pixels.point(lambda x: x*1.9)
AttributeError: 'MyApp' object has no attribute 'pixels'
As you can tell I'm new to programming so any help to send me on the right track would be awesome.

Below is a complete solution that works. These are a few comments on the changes that were made:
Previously the __init__ method never returned because it calls self.root.mainloop() at the end. Which can cause some issues. I restructured it to be more like the hello world example in the python docs.
There is a great Darken/Lighten Example that is what the brighten() method is modeled around.
there was a from Tkinter import *, this replaced by from Tkinter import Frame, Tk, Label, Button. it turns out that both PIL and Tkinter have an attribute called Image which was really confusing to work with. Try and avoid the use of from module import * and instead be explicit in what you are importing this will prevent name space collisions.
code
from Tkinter import Frame, Tk, Label, Button
from PIL import Image, ImageTk, ImageFilter
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
master.wm_title("Image examples")
self.pack()
self.createWidgets()
def createWidgets(self):
self.img = Image.open("lineage.jpg")
self.photo1 = ImageTk.PhotoImage(self.img.convert("RGB"))
self.label1 = Label(self, image=self.photo1)
self.label1.grid(row=0, column=0)
self.photo2 = ImageTk.PhotoImage(self.img.convert("RGB"))
self.label2 = Label(self, image=self.photo2)
self.label2.grid(row=0, column=1)
button = Button(self, text="Brighten", command=self.brighten)
button.grid(row=0, column=2)
def brighten(self):
img2 = self.img.point(lambda p: p * 1.9)
self.photo2 = ImageTk.PhotoImage(img2)
self.label2 = Label(self, image=self.photo2)
self.label2.grid(row=0, column=1)
root = Tk()
app = Application(master=root)
app.mainloop()
root.destroy()

I got a working one.
from __future__ import division
from Tkinter import *
from PIL import Image, ImageTk, ImageFilter
import random
class MyApp(object):
def __init__(self):
self.root = Tk()
self.root.wm_title("Image examples")
img = Image.open("lineage.jpg").convert("RGB")
(self.w, self.h) = (img.size[0], img.size[1])
self.tkpi = ImageTk.PhotoImage(img)
self.label = Label(self.root, image=self.tkpi)
self.label.grid(row=0, column=0, padx=5, pady=5, rowspan=10)
self.img2 = img.copy()
self.pixels = self.img2.load()
self.width, self.height = self.img2.size
self.tkpi2 = ImageTk.PhotoImage(self.img2)
self.label2 = Label(self.root, image=self.tkpi2)
self.label2.grid(row=0, column=1, padx=5, pady=5, rowspan=10)
self.btn = Button(self.root, text="Brighten")
self.btn.grid(row=0, column= 2)
self.btn.bind('<Button-1>', self.brighten)
self.root.mainloop()
def brighten(self,*args):
# self.pixels = self.pixels.point(lambda x: x*1.9)
for i in range(self.w): # for every pixel:
for j in range(self.h):
# print self.pixels[i,j]
self.pixels[i,j] = (int(self.pixels[i,j][0] * 1.9),
int(self.pixels[i,j][1] * 1.9),
int(self.pixels[i,j][2] * 1.9))
self.tkpi2 = ImageTk.PhotoImage(self.img2)
self.label2.configure(image = self.tkpi2)
self.root.update_idletasks()
MyApp()

Related

Tkinter LabelFrames don't show up

When i want to layout my frames the Labels don't show up. I can't seem to solve it. For some reason it does show op the entries that i've made. Can somebody please help me.
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from PIL import ImageTk, Image
class main_screen():
def __init__(self, master):
self.master = master
self.master.title("Roboframe")
self.master.geometry("650x650")
self.create_frames()
self.create_entries()
def create_frames(self):
self.top = Frame(self.master).grid(row=0,column=0)
self.bottom = Frame(self.master).grid(row=0, column=0)
self.set_paths = LabelFrame(self.master, text="Set Path", padx=10, pady=10).grid(row=0,column=0)
self.options = LabelFrame(self.master, text="Options", padx=10, pady=10).grid(row=0,column=0)
def create_entries(self):
python_path = StringVar(self.set_paths, "C:/Python37/python.exe")
robot_path = StringVar(self.set_paths, "C:/ws/cmge.automation/RobotFrameworkCMGE")
self.set_path_python = Entry(self.set_paths, width=60, textvariable=python_path).grid(row=0,column=0)
self.set_path_robot = Entry(self.set_paths, width=60, textvariable=robot_path).grid(row=1, column=0)
root = tk.Tk()
app = main_screen(root)
root.mainloop()
Output of code shown above
The thing i'm rewritting the code for because it is a mess
The second picture i've also made myself. But the code is a giant mess.
You have to make an object of the widget not the grid function of the widget. Grid returns nothing so naturally none of them will show up. I believe this is what you wanted:
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from PIL import ImageTk, Image
class main_screen():
def __init__(self, master):
self.master = master
self.master.title("Roboframe")
self.master.geometry("650x650")
self.create_frames()
self.create_entries()
def create_frames(self):
# you have grided all of your frames and label frames on the same row and column
self.top = Frame(self.master)
self.top.grid(row=0,column=0)
self.bottom = Frame(self.master)
self.bottom.grid(row=0, column=0)
self.set_paths = LabelFrame(self.master, text="Set Path", padx=10, pady=10)
self.set_paths.grid(row=0,column=0)
self.options = LabelFrame(self.master, text="Options", padx=10, pady=10)
self.options.grid(row=0,column=0)
def create_entries(self):
python_path = StringVar(self.set_paths, "C:/Python37/python.exe")
robot_path = StringVar(self.set_paths, "C:/ws/cmge.automation/RobotFrameworkCMGE")
self.set_path_python = Entry(self.set_paths, width=60, textvariable=python_path)
self.set_path_python.grid(row=0,column=0)
self.set_path_robot = Entry(self.set_paths, width=60, textvariable=robot_path)
self.set_path_robot.grid(row=1, column=0)
root = tk.Tk()
app = main_screen(root)
root.mainloop()
Also a couple of things:
You have imported tkinter twice in two different ways, just use one of them
You are griding both of the LabelFrames and frames on the same row and column but since "self.options" does not contain anything it is not going to show up, be careful later on
This will display both LabelFrames, the second with a dummy Entry widget.
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from PIL import ImageTk, Image
class main_screen():
def __init__(self, master):
self.master = master
self.master.title("Roboframe")
self.master.geometry("650x650")
self.create_frames()
self.create_entries()
def create_frames(self):
self.set_paths = LabelFrame(self.master, text="Set Path", padx=10, pady=10)
self.set_paths.grid(row=0,column=0)
self.options = LabelFrame(self.master, text="Options", padx=10, pady=10)
self.options.grid(row=1,column=0)
def create_entries(self):
python_path = StringVar(self.set_paths, "C:/Python37/python.exe")
robot_path = StringVar(self.set_paths, "C:/ws/cmge.automation/RobotFrameworkCMGE")
self.set_path_python = Entry(self.set_paths, width=60, textvariable=python_path)
self.set_path_python.grid(row=0,column=0)
self.set_path_robot = Entry(self.set_paths, width=60, textvariable=robot_path)
self.set_path_robot.grid(row=1, column=0)
self.test = Entry(self.options, width=60)
self.test.grid(row=1, column=1)
root = tk.Tk()
app = main_screen(root)
root.mainloop()

How do I create an image button - Python [duplicate]

This question already has an answer here:
Create image in button
(1 answer)
Closed 3 years ago.
For the buttons, I want to change the "text" to be "images"
e.g picture of a eraser instead of text saying eraser.
Here is the Section of Code:
def __init__(self):
self.root = Tk()
self.choose_size_button = Scale(self.root, from_=1, to=15, orient=HORIZONTAL)
self.choose_size_button.grid(row=0, column=1)
self.draw_button = Button(self.root, text='Draw', command=self.use_draw)
self.draw_button.grid(row=0, column=2)
self.color_button = Button(self.root, text='Colour', command=self.choose_color)
self.color_button.grid(row=0, column=3)
self.eraser_button = Button(self.root, text='Eraser', command=self.use_eraser)
self.eraser_button.grid(row=0, column=4)
self.c = Canvas(self.root, bg='white', width=650, height=600)
self.c.grid(row=1, columnspan=5)
self.setup()
self.root.mainloop()
You should use the tinkter to perform your task. You can pass image argument to the button.
For example:
import Tkinter as tk
class View(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.image = tk.PhotoImage(file="anyfile.gif")
b = tk.Button(self, text=" ", image=self.image)
b.pack(side="top")
if __name__ == "__main__":
root = tk.Tk()
view = View(root)
view.pack(side="top", fill="both", expand=True)
root.mainloop()
You can use image argument of Button in tkinter.
For example; see this snippet:-
from tkinter import *
from PIL import ImageTk, Image
root = Tk()
img = ImageTk.PhotoImage(Image.open('your_image_path'))
b = Button(root, command = print('hello'), image = img)
b.pack()
b.place()

Tkinter PhotoImage won't Work

I have been creating a file that displays a image on a canvas. I created the 'PhotoImage' file that I use to store my picture.
d = PhotoImage(file="pic.gif")
canvas = Canvas(root, 500, 500)
pic = canvas.create_image(20, 20, image=d)
But I just produce an error each time I run the program...for some reason, PhotoImage will never work for me. How do I get this to work?
This is a an example that works for me.
#----------------------------------------------------------------------
import Tkinter
#----------------------------------------------------------------------
root = Tkinter.Tk()
frame = Tkinter.Frame(root)
frame = Tkinter.LabelFrame(root, text="LabelFrame text", padx=5, pady=5)
frame.pack(side=Tkinter.LEFT)
Label1 = Tkinter.Label(frame, text="Label1 text")
Label1.pack()
#----------------------------------------------------------------------
photo1 = Tkinter.PhotoImage(file = 'Chart_Example.gif')
#
width_1 = photo1.width()
height_1 = photo1.height()
#
x_center_1 = width_1 / 2.0
y_center_1 = height_1 / 2.0
#---------------------------------
iframe1 = Tkinter.Frame(frame, bd=2, relief=Tkinter.RAISED)
iframe1.pack(expand=1, fill=Tkinter.X, pady=5, padx=5, side=Tkinter.LEFT)
c1 = Tkinter.Canvas(iframe1, width=width_1, height=height_1)
c1.create_image(x_center_1, y_center_1, image=photo1, anchor = Tkinter.CENTER)
c1.pack(side=Tkinter.LEFT)
#----------------------------------------------------------------------
root.mainloop()
#----------------------------------------------------------------------

Generating 300+ images causes the images after the 300th or so image to not show up Python Tkinter

I am working on a program where the user can look at many images which are in a frame in a canvas to make the frame scroll able. But if I load more than 300 images. After it hits the 300 mark the images after that do not show up on the canvass but it lets you still scroll as if they are there so you are only looking at the Gray background.
Why is this happening?
How could I fix this?
Code:
from PIL import ImageTk, Image as im
from cStringIO import StringIO
from threading import Thread
from Tkinter import *
import ttk
import os
class Application(Frame):
def __init__(self, parent):
Frame.__init__(self,parent)
self.pack(fill=BOTH)
root.protocol("WM_DELETE_WINDOW", self.closeApp)
self.images = []
self.image = "Image.png" #Image is 200x100
self.temp = ""
self.create_Browse()
def create_Browse(self):
self.tfr = Frame(self, height=25, width=650)
self.tfr.pack_propagate(False)
self.tfr.pack(side=TOP)
self.menuBar = Frame(self.tfr, bg="lightGray")
self.menuBar.pack(side=TOP, fill=X)
self.menuButton = Label(self.menuBar, font=("Arial", 13), width=10, text="Menu <")
self.menuButton.pack(side=LEFT)
self.mfr = Frame(self, bd=0)
self.mfr.pack(side=TOP)
self.scroller = Scrollbar(self.mfr, orient=VERTICAL)
self.scroller.pack(side=RIGHT, fill=Y)
self.viewArea = Canvas(self.mfr, bg="Gray", height=475, width=650, bd=0, highlightbackground="Gray")
self.viewArea.pack(side=TOP, fill=BOTH)
self.mfr2 = Frame(self.viewArea, height=475, width=65, bg="Gray", bd=0)
self.mfr2.pack(side=TOP, fill=BOTH)
self.scroller.configure(command=self.viewArea.yview)
self.viewArea.configure(yscrollcommand=self.scroller.set)
self.viewArea.create_window((0,0), window=self.mfr2, anchor=NW)
self.mfr2.bind("<Configure>", self.scroll)
self.scroller.bind_all("<MouseWheel>", self.mouseWheel)
def generate():
num = 0
count = 0
while count < 500:
frame = Frame(self.mfr2, bg="Gray")
frame.pack(side=TOP, fill=X)
label = Label(frame, image=img, bg="Gray")
label.image = img
if i == 0:
label.pack(side=LEFT, padx=(8, 0))
else:
label.pack(side=LEFT)
num += 1
count += 1
for i in range(3):
img = ImageTk.PhotoImage(im.open(self.image))
generate()
def mouseWheel(self, event):
self.viewArea.yview_scroll(-1*(event.delta/120), "units")
def scroll(self, event):
self.viewArea.configure(scrollregion=self.viewArea.bbox("all"), bg="Gray", bd=0)
def closeApp(self):
os._exit(0)
root = Tk()
root.title("Byte Vortex")
root.resizable(0,0)
root.geometry("650x500")
root.iconbitmap("Files/System_Files/icon.ico")
app = Application(root)
root.mainloop()

how to set background image to a window using Tkinter python 2.7

I was working on setting the background image and upon that image adding the labels, buttons and all. everything is coming, but not on the background image, its like this:
And my code is:
from Tkinter import Tk, Frame, BOTH
import Tkinter
from PIL import Image, ImageTk
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("PISE")
self.pack(fill=BOTH, expand=1)
root = Tk()
root.geometry("1111x675+300+300")
app = Example(root)
im = Image.open('wood.png')
tkimage = ImageTk.PhotoImage(im)
Tkinter.Label(root,image = tkimage).pack()
custName = StringVar(None)
yourName = Entry(app, textvariable=custName)
yourName.pack()
relStatus = StringVar()
relStatus.set(None)
labelText = StringVar()
labelText.set('Accuracy Level')
label1 = Label(app, textvariable=labelText, height=2)
label1.pack()
radio1 = Radiobutton(app, text='100%', value='1', variable = relStatus, command=beenClicked1).pack()
radio2 = Radiobutton(app, text='50%', value='5', variable = relStatus, command=beenClicked5).pack()
root.mainloop()
How to fit the background image properly?
Thanks in advance!
You should use place() for placing the image & then use grid() (personally i prefer grid) or pack() for other widgets.
from Tkinter import Tk, Frame, BOTH
import Tkinter
from PIL import Image, ImageTk
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("PISE")
self.pack(fill=BOTH, expand=1)
root = Tk()
root.geometry("1111x675+300+300")
app = Example(root)
im = Image.open('Test1.png')
tkimage = ImageTk.PhotoImage(im)
myvar=Tkinter.Label(root,image = tkimage)
myvar.place(x=0, y=0, relwidth=1, relheight=1)
custName = StringVar(None)
yourName = Entry(root, textvariable=custName)
yourName.pack()
relStatus = StringVar()
relStatus.set(None)
labelText = StringVar()
labelText.set('Accuracy Level')
label1 = Label(root, textvariable=labelText, height=2)
label1.pack()
def beenClicked1():
pass
def beenClicked5():
pass
radio1 = Radiobutton(root, text='100%', value='1', variable = relStatus, command=beenClicked1).pack()
radio2 = Radiobutton(root, text='50%', value='5', variable = relStatus, command=beenClicked5).pack()
root.mainloop()
The reason the widgets were not visible was because you were using two different parents ,i.e, app(its an Instance of class Example,so don't use this) and root.

Categories

Resources