I am trying to add a bunch of images from a folder using a for loop using tkinter and I want each image to be placed on row = 20, but change columns for each image. So , I will want an image on (20,10), (20,11), (20,12) and so on. This works when I use grid for individual images, but I cant get it to work in a for loop where I want to add 5 images. Instead my first image starts appearing in the first row and first column but follows the column increments. Please let me know what I am doing wrong here? Thanks!
game = tkinter.Tk()
game.geometry("500x500")
images = random.sample(deck, 5)
path = "C:/Users/jhbhb/Documents/"
MAX_ROWS = 4
current_row = 20
current_column = 10
for file in images:
im = Image.open(f"{path}/{file}.png")
photo = ImageTk.PhotoImage(im)
label = tkinter.Label(image=photo)
label.image = photo
label.grid(row=current_row, column=current_column)
current_column += 1
game.mainloop()
Related
I am trying to combine 4 images, image 1 on top left, image 2 on top right, image 3 on bottom left and image 4 on bottom right. However, my images are different sizes and not sure how to resize the images to same size. I am pretty new to Python and this is my first time using PIL.
I have this so far (after opening the images)
img1 = img1.resize(img2.size)
img1 = img1.resize(img3.size)
img1 = img1.resize(img4.size)
This shall suffice your basic requirement.
This shall suffice your basic requirement.
Steps:
Images are read and stored to list of arrays using io.imread(img) in
a list comprehension.
We resize images to custom height and width.You can change IMAGE_WIDTH,IMAGE_HEIGHT as per your need with respect
to the input image size.
You just have to pass the location of n
images (n=4 for your case) to the function.
If you are
passing more than 2 images (for your case 4), it will work create 2
rows of images. In the top row, images in the first half of the list
are stacked and the remaining ones are placed in bottom row using
hconcat().
The two rows are stacked vertically using vconcat().
Finally, we convert the result to RGB image using
image.convert("RGB") and is saved using image.save().
The code:
import cv2
from PIL import Image
from skimage import io
IMAGE_WIDTH = 1920
IMAGE_HEIGHT = 1080
def create_collage(images):
images = [io.imread(img) for img in images]
images = [cv2.resize(image, (IMAGE_WIDTH, IMAGE_HEIGHT)) for image in images]
if len(images) > 2:
half = len(images) // 2
h1 = cv2.hconcat(images[:half])
h2 = cv2.hconcat(images[half:])
concat_images = cv2.vconcat([h1, h2])
else:
concat_images = cv2.hconcat(images)
image = Image.fromarray(concat_images)
# Image path
image_name = "result.jpg"
image = image.convert("RGB")
image.save(f"{image_name}")
return image_name
images=["image1.png","image2.png","image3.png","image4.png"]
#image1 on top left, image2 on top right, image3 on bottom left,image4 on bottom right
create_collage(images)
To create advanced college make you can look into this:
https://codereview.stackexchange.com/questions/275727/python-3-script-to-make-photo-collages
I am trying to improve my code to make it more userfriendly using GUI. I have a simple code to select set of images and crop it. I have a code to that selects the folder directory containing images, now I want something similar using tkinter to select pixel range to crop images in the following code.
#Read images
root= tk.Tk()
var = tk.StringVar()
label = tk.Label( root, textvariable=var,relief = tk.RAISED,fg='peru',bg='white',font=('Helvetica',18,'bold'))
var.set("Choose image location")
label.pack()
img_list =[i for i in glob.glob(filedialog.askdirectory() +'/*.tif')] # choose the folder containing image list
images_read = np.array([(plt.imread(fname)) for fname in img_list]).astype(np.int32)
#crop_size=input()
images_crp =np.array([i[524:1024,275:775] for i in images_flp]) #crop the images to requried shape (or Pixel_row X pixel_column)
Here, I have manually selected pixel range, but I would love to have a pop up window asking me to enter the pixel range using GUI. Help in this regard is appreciated.
Thanks
Hey guys I've been trying to merge 2 images(one is a green screen image with a object in the middle of the photo, the second one is a of a forest) using PIL. Both images are the same size(800, 600) I've tried to merge them into a new image but its seeming impossible at my end.
Any code solution?
I would break the problem down into pieces: first you're going to want to remove the green screen background from your first image. You can do this with PIL by iterating through every frame of the video and removing the green color. There are great guides to do so online.
Next, you're going to want to put the first image on top of the second. You can achieve that using the paste() method, also detailed in online guides.
I am also new in Python, but our instructor gave another way to get this done by using if conditions and nested for loops
*from PIL import Image
penguin_image = Image.open ("penguin.jpg")
beach_image = Image.open("beach.jpg")
penguin_width, penguin_height = penguin_image.size
#Accessing the pixels of the images
penguin_pixel = penguin_image.load()
beach_pixel = beach_image.load()
#Image inspection
(r0,g0,b0) = penguin_pixel[0,0]
(r1,g1,b1) = penguin_pixel[1,0]
(r2,g2,b2) = penguin_pixel[2,0]
(r3,g3,b3) = penguin_pixel[3,0]
(r4,g4,b4) = penguin_pixel[4,0]
(r5,g5,b5) = penguin_pixel[5,0]
(br,bg,bb) = beach_pixel[0,0]
print(penguin_width, penguin_height)
print(br, bg, bb)
#Creation of new image to hold combined pixels
combined_image = Image.new("RGB", penguin_image.size)
combined_pixel = combined_image.load()
#Checking for green
for ver in range (0, penguin_height):
for hor in range(0, penguin_width):
(r,g,b) = penguin_pixel[hor, ver]
(br,bg,bb) = beach_pixel[hor, ver]
if (r < 100 and g == 207 and b < 100):
combined_pixel[hor,ver] = (br, bg, bb)
else:
combined_pixel[hor,ver] = (r, g, b)*
combined_image.show()
I want to stitch a series of images together using the Python Imaging Library. However, the images I want to stitch together are contained in two separate directories. Is PIL able to stitch images under this condition?
I have two series of 10 images stored in two directories - let's call them D1 and D2. I would like to use PIL to stitch Image 1 from D1 with Image 1 from D2, Image 2 from D1 with Image 2 from D2, etc. I have a third directory, D3, in which I would like to save the stitched output images.
I thought the correct way to do this would be to use the code snipped provided by user d3ming in [this example] (Stitching Photos together) and use nested for loops to loop over D1 and D2 to provide input images.
Here is the code that I have currently:
list_im1 = sorted(glob.glob(in_dir_1+"*")) #make list of first set of images
list_im2 = sorted(glob.glob(in_dir_2+"*")) #make list of second set of images
def merge_images(file1, file2):
"""Merge two images into one, displayed side by side
:param file1: path to first image file
:param file2: path to second image file
:return: the merged Image object
"""
image1 = Image.open(file1)
image2 = Image.open(file2)
(width1, height1) = image1.size
(width2, height2) = image2.size
result_width = width1 + width2
result_height = max(height1, height2)
result = Image.new('RGB', (result_width, result_height))
result.paste(im=image1, box=(0, 0))
result.paste(im=image2, box=(width1, 0))
return result
merged = merge_images(file1, file2)
merged.save(out_dir)
for i in in_dir_1: #first loop through D1
for j in in_dir_2: #second loop through D2
merge_images(i, j)
I expected that this code snippet, combined with the nested loop, would run through in_dir_1 (D1), search through the image with the same position in in_dir_2 (D2), and return me a series of 10 stitched images in out_dir (D3). However, my code is not returning any output images at all.
Any help will be greatly appreciated.
Immediate solution is replacing the return statement with Image.save().
list_im1 = sorted(glob.glob(in_dir_1+"*")) #make list of first set of images
list_im2 = sorted(glob.glob(in_dir_2+"*")) #make list of second set of images
def merge_images(file1, file2):
"""Merge two images into one, displayed side by side
:param file1: path to first image file
:param file2: path to second image file
"""
global ctr
image1 = Image.open(file1)
image2 = Image.open(file2)
(width1, height1) = image1.size
(width2, height2) = image2.size
result_width = width1 + width2
result_height = max(height1, height2)
result = Image.new('RGB', (result_width, result_height))
result.paste(im=image1, box=(0, 0))
result.paste(im=image2, box=(width1, 0))
result.save(out_dir + str(ctr) + ".png")
ctr += 1
ctr = 1
for i in in_dir_1: #first loop through D1
for j in in_dir_2: #second loop through D2
merge_images(i, j)
I would suggest you to use a dynamic output image file path (out_dir), meaning the file path should change with different files. Otherwise same image file would be overwritten over and over as the program goes on.
EDIT:-
If you want each image to be saved distinctly, then you can use a counter (just a number to keep track of which image is being processed).
I will be using a global variable which will increment the value of the variable each time a new image has been processed.
Edited the code accordingly.
EDIT 2:-
Since, each image has it's pair, therefore the total number of images in both the folder will be same. So you can use eval() instead of using a pair of for loops in order to get through that issue.
Just replace:-
for i in in_dir_1:
for j in in_dir_2:
merge_images(i, j)
By:-
for i, x in eval(in_dir_1):
merge_images(in_dir_1[i], in_dir_2[i])
I encountered a problem as I tried to fill a tkinter grid with a loop
i=0
for category in categories:
self.image = PhotoImage(file=category[2]+".png")
imageLabel = Label(master, image=self.image)
imageLabel.grid(row=0, column=i)
i = i + 1
With this code I try to create a row with different pictures side by side.
But it shows only the last image which is in the categories array (this array was filled by a SQL-execute btw).
After a few researches I found out, that it seems that python overwrites the reference of the picture on each iteration.
So I tried to change the code and save the references in a array:
folderPictures = []
i = 0
for category in categories:
self.image = PhotoImage(file=category[2]+".png")
imageLabel = Label(master, image=self.image)
folderPictures.append(imageLabel)
for pictures in folderPictures:
pictures.grid(row=0, column=i)
i = +1
unfortunately this doesn't work either. What do I do wrong?
Thanks and best regards
Franz
Instead of overwriting self.image each time, keep a separate reference for each image. For instance, you could make self.image into an array (self.images[0,1,...]) and keep each image in a different slot.
Load images first and make a list of them, then put in label.
images=[]
for category in categories:
images.append(PhotoImage(file=category[2]+".png"))
for index,img in enumerate(images):
Label(master,image=img).grid(row=0,column=index)
I saved the reference of the label instead of the ref of the picture.
self.image = []
for category in categories:
self.image.append(PhotoImage(file=category[2]+".png"))
imageLabel = Label(master, image=self.image[i])
imageLabel.grid(row=0, column=i)
i = i + 1
this works now!