0

I want to resize a folder of images after writing the height and width in textboxes and I need to save this resized folder, using tkinter.I began with this code :

import tkinter as tk 
from PIL import ImageTk, Image
from tkinter import filedialog
import os

root = Tk()
root.geometry("800x600")
src_file = StringVar()
imgWidth = IntVar()
imgHeight = IntVar()

def open_filedialog():
      global  folder
      folder = filedialog.askdirectory()
      src_file.set(folder) 

label = Label(wrapper, text="Source File")
label.pack(side=LEFT, padx=10, pady=10)

entry = Entry(wrapper, textvariable = src_file,width="50")
entry.pack(side = LEFT, padx=10, pady=10)

select_btn = Button(wrapper , text="Select Image",command= open_filedialog)
select_btn.pack(side= LEFT, padx=10,pady=10)

width_box = Entry(imageResize_wrapper,textvariable = imgWidth)
width_box.pack(side=LEFT, padx=10, pady=10)

height_box = Entry(imageResize_wrapper,textvariable = imgHeight)
height_box.pack(side=LEFT, padx=10, pady=10)

set_btn = Button(imageResize_wrapper, text = "Set",font=(
 "Consaolas", 16),fg="#000", command = set_imageSize)
set_btn.pack(side= LEFT, padx=10, pady=10)

root.mainloop()
laila
  • 1
  • 1
  • So you want to resize the images in the folders and save them –  Jun 14 '21 at 04:59
  • You can use OpenCV for resizing. For example, `resized_img = cv2.resize(img, (imgWidth.get(),imgHeight.get()), interpolation = cv2.INTER_CUBIC)`. And also you need to get the selected folder's path. Then you can resize or whatever you want that files in the folder. Check this answer https://stackoverflow.com/a/21518989/13560126 – ablmmcu Jun 14 '21 at 10:05
  • Please clarify what You want and provide what You have tried since the given code does almost nothing or You haven't provided enough of it since for example I don't see the `set_imageSize` (which btw per PEP8 should be sth like `set_image_size`) function – Matiiss Jun 14 '21 at 10:25

2 Answers2

0

Here is a solution:

from tkinter import Tk, Label, Entry, Button, Frame
from tkinter.filedialog import askdirectory
from PIL import Image
import os


def get_dir():
    directory = askdirectory()
    dir_lbl.config(text=directory)


def convert_images():
    source = dir_lbl.cget('text')
    extension = '.png'
    w = int(width.get())
    h = int(height.get())
    image_list = [source + '/' + file for file in os.listdir(path=source) if extension in file]
    new_dir = source + '_converted'
    os.mkdir(new_dir)

    for image in image_list:
        print(image)
        img = Image.open(image)
        img = img.resize((w, h), Image.ANTIALIAS)
        img.save(new_dir + f'/{image.split("/")[-1]}')


root = Tk()
root.geometry('500x300')

dir_frame = Frame(root)
dir_frame.pack(pady=10)

Button(dir_frame, text='Choose Directory', command=get_dir).pack()
dir_lbl = Label(dir_frame, text='')
dir_lbl.pack()

settings_frame = Frame(root)
settings_frame.pack(pady=10)

width_frame = Frame(settings_frame)
width_frame.pack()
Label(width_frame, text='Width: ').pack(side='left')
width = Entry(width_frame)
width.pack(side='right')

height_frame = Frame(settings_frame)
height_frame.pack()
Label(height_frame, text='Height: ').pack(side='left')
height = Entry(height_frame)
height.pack(side='right')

Button(settings_frame, text='Convert All', command=convert_images).pack(pady=10)

root.mainloop()

First to mention is that there can be added a lot of other options for users to choose from and what to do with pictures for example allow stepping through each image or maybe allow choosing their own directory name but the simple stuff is here.

Explanation First import all necessary stuff: libraries, modules, classes and stuff

Then a function is defined to get the directory user will choose. It is a simple process: use the built-in method to call the "chooser" and place the returned string which is the path to the directory on the label both for displaying the user what he has chosen and to store a reference.

The the other function which is the most important gets defined. First get the text from the label using .cget method of widgets in tkinter (could also use sth like dir_lbl['text'] or sth else). That will be the source directory. Then define an extension just for readability and if in future an argument gets added it is easier to change stuff. Next get the user inputed width and height of the resized images (should add something to prevent users from entering wrong data), then create a list of all the images in that directory which is done using list comprehensions. (If You don't know about them You should read since for such reasons they are super great) but basically what it does is add all the files that have .png in their file names (so theoretically something like image.png.jpg could be added too but that is pretty rare if at all would happen, again could improve on this). Then a new directory name (and path) is created by basically just adding "_converted" at the end of the current directory name (again could change that to be user chosen or sth). Then use os module to create a new directory (probably only works for windows so could use something that is a bit more cross-platform). Then loops over all those images, opens them and resizes them, then saves in the new directory.

The rest of the code is just pretty much pure tkinter and there is not much to explain about it.

If You have any questions ask them.

Matiiss
  • 5,970
  • 2
  • 12
  • 29
  • I need resize many image file types. how can i include more extensions (.jpg, .svg, .gif etc..) in this code. – laila Jun 15 '21 at 11:29
  • actually I did a bit wrong because ther is a simple way to actually check the actual extension (the last bit). ok what You would want to do then is extend the `extension` string for example simply do sth like this `extension = '.png, .jpg, .jpeg'` for readability purposes however it is possible to just do `extension = 'pngjpgjpeg'` however that is not as readable (also these changes have to be made with the next changes): change the list comprehension to this: `image_list = [source + '/' + file for file in os.listdir(path=source) if file.split('.')[-1] in extension]` – Matiiss Jun 15 '21 at 11:33
  • this will check the actual extension of the file so that issue is solved (talked about it in my answer) and it will check it against that string so basically if those last letters after . are in that string they will match so the file path will be added. also could then rename the variable to `extensions` – Matiiss Jun 15 '21 at 11:34
0

I tried this code.it work with me.

from tkinter import *
from PIL import ImageTk, Image
from tkinter import filedialog
import os, sys, glob


root = Tk()
root.geometry("800x600")

src_file = StringVar()
imgWidth = IntVar()
imgHeight = IntVar()


def open_filedialog():
    folder = filedialog.askdirectory( parent = root)
    src_file.set(folder)
    

#resize image
def set_image_size():
    root_dir = src_file  
    nw = int(imgWidth.get())
    nh = int(imgHeight.get()) 
    for file in glob.iglob(root_dir.get() +'**/*.jpg', recursive=True) : 
        print(file)
        im = Image.open(file)
        imResize = im.resize((nw,nh), Image.ANTIALIAS)
        imResize.save(file)    
        imResize.save(file)

    
           

wrapper = LabelFrame(root,text="Source File")
wrapper.pack(fill="both",expand="yes",padx=20,pady=20)

imageResize_wrapper = LabelFrame(root,text="Resize")
imageResize_wrapper.pack(fill="both",expand="yes",padx=20,pady=20)

Image_wrapper = LabelFrame(root, text="Image")
Image_wrapper.pack(fill="both",expand="yes",padx="20",pady=20)

#wrapper 
label = Label(wrapper, text="Source File")
label.pack(side=LEFT, padx=10, pady=10)

entry = Entry(wrapper, textvariable = src_file,width="50")
entry.pack(side = LEFT, padx=10, pady=10)

select_btn = Button(wrapper , text="Select Image",command= open_filedialog)
select_btn.pack(side= LEFT, padx=10,pady=10)
# wrapper 

#image Resize wrapper 
width_lbl = Label(imageResize_wrapper, text="width", font=(
    "Consaolas", 16),fg="#000", bg="#DF9B6D")
width_lbl.pack(side=LEFT,padx=10, pady=10)

width_box = Entry(imageResize_wrapper,textvariable = imgWidth)
width_box.pack(side=LEFT, padx=10, pady=10)

height_lbl = Label(imageResize_wrapper, text="Height", font=(
    "Consaolas", 16),fg="#000", bg="#DF9B6D")
height_lbl.pack(side=LEFT,padx=10, pady=10)

height_box = Entry(imageResize_wrapper,textvariable = imgHeight)
height_box.pack(side=LEFT, padx=10, pady=10)

set_btn = Button(imageResize_wrapper, text = "resize and save",font=(
    "Consaolas", 16),fg="#000", command = set_image_size)
set_btn.pack(side= LEFT, padx=10, pady=10)



root.mainloop()

but I need to include more extensions (.jpg,.jpeg etc..) in glob.iglob().How can I edit the above code to achieve it.

laila
  • 1
  • 1