Mar-03-2023, 06:37 PM
Thanks deanhystad . I rewrote the whole script and its working. However I have a few issues.
1) There seems to be lag in loading of the first image.
2) I would like to have the exit button to stop the program and allow for a new file/ folder to be selected .
1) There seems to be lag in loading of the first image.
2) I would like to have the exit button to stop the program and allow for a new file/ folder to be selected .
import fitz # PyMuPDF import io import os import tempfile import PIL.Image from PIL import ImageTk import tkinter as tk from tkinter import filedialog from tkinter import * root = tk.Tk() root.title("Viewer") photo=PhotoImage(file="C:\\Users\\INDIAN\Desktop\\python exercises\\Viewer\\Logo Viewer.png") label = Label(root,image = photo,bg="light blue") label.image = photo # keep a reference! label.grid(column=12,row=1,rowspan=2 ,ipadx=5, ipady=5,sticky=tk.W) root.geometry("1200x800") root.configure(background='light blue') tk.Label(root, text="Viewer",font="Algerian 20 bold",bg="light blue").grid(column=12,row=1, ipadx=150, ipady=10,sticky=tk.NE) canvas = tk.Canvas(root, width=800, height=600,bg='black') canvas.grid(column=1,row=1,columnspan=10,ipadx=10,ipady=10,sticky=tk.NW) ############################################################################################ # Create a temporary directory temp_dir = tempfile.TemporaryDirectory() print(f"[+] All images saved to {temp_dir}") ############################################################################################### def select_pdf_file(): global images # open file dialog to choose a PDF file file_path = filedialog.askopenfilename(filetypes=[("PDF Files", "*.pdf")]) if file_path: # open the file pdf_file = fitz.open(file_path) for page_index in range(len(pdf_file)): # get the page itself page = pdf_file[page_index] # get image list image_list = page.get_images() # printing number of images found in this page if image_list: print(f"[+] Found a total of {len(image_list)} images in page {page_index}") else: print("[!] No images found on page", page_index) for image_index, img in enumerate(image_list, start=1): # get the XREF of the image xref = img[0] # extract the image bytes base_image = pdf_file.extract_image(xref) image_bytes = base_image["image"] # get the image extension image_ext = base_image["ext"] # load it to PIL image = PIL.Image.open(io.BytesIO(image_bytes)) # save it to temporary folder image.save(os.path.join(temp_dir.name, f"image{page_index+1}_{image_index}.{image_ext}")) print(f"[+] All images saved to {temp_dir}") # iterate over the image files in the temporary folder and display them image_files = sorted(os.listdir(temp_dir.name)) global current_index current_index = 0 images = [] for filename in os.listdir(temp_dir.name): if filename.endswith('.png') or filename.endswith('.bmp') or filename.endswith('.jpg') or filename.endswith('.bmp') or filename.endswith('.dcm'): images.append(os.path.join(temp_dir.name, filename)) if images: show_image(0, images) #################################################################################################### def select_folder(): global images global folder_path # Open a file dialog to select the folder folder_path = filedialog.askdirectory() # Load the images from the selected folder images=[] for filename in os.listdir(folder_path): if filename.endswith('.png') or filename.endswith('.bmp') or filename.endswith('.jpg') or filename.endswith('.bmp') or filename.endswith('.dcm'): images.append(os.path.join(folder_path,filename)) show_image(0, images) global current_index current_index = 0 ###################################################################################################### def show_image(index, images): global current_index current_index = index image_path = images[index] image = PIL.Image.open(image_path) image = image.resize((800, 600)) photo = ImageTk.PhotoImage(image) canvas.create_image(0, 0, anchor=tk.NW, image=photo) canvas.image = photo current_index = index ###################################################################################################### def on_left_arrow(event): global current_index if current_index > 0: current_index -= 1 show_image(current_index, images) def on_right_arrow(event): global current_index if current_index < len(images) - 1: current_index += 1 show_image(current_index, images) def exit_program(): root.destroy() ########################################################################## # Set the initial image current_image = 0 ## Button & packing it and assigning it a command tk.Button(text=" Select PDF ", command=select_pdf_file).grid(row=13, column=11) button1 = tk.Button(root, text="Select Folder", command=select_folder).grid(row=13,column=12) button2 = tk.Button(root, text="Exit", command=select_folder).grid(row=13,column=12,padx=60,pady=0,sticky=tk.W) # bind the arrow keys to navigate the images root.bind('<Left>', on_left_arrow) root.bind('<Right>',on_right_arrow) ##Button(text=" Select File ",command=select_pdf_file).grid(row=13, column=3) root.mainloop()
(Feb-28-2023, 05:04 PM)deanhystad Wrote: https://docs.python.org/3/library/tempfile.html
Quote:class tempfile.TemporaryDirectory(suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False)
This class securely creates a temporary directory using the same rules as mkdtemp(). The resulting object can be used as a context manager (see Examples). On completion of the context or destruction of the temporary directory object, the newly created temporary directory and all its contents are removed from the filesystem.
In other words, as soon as you leave the context created by this:
with tempfile.TemporaryDirectory() as temp_folder:The temporary directory is deleted.
There is no need to write the image data to files. Create the images and keep them in a list. If you want to write files to a temporary directory, you could wrap you program in the temp_folder context.
with tempfile.TemporaryDirectory() as temp_folder: window = function_that_creates_your_main_window() window.mainloop()Or you could make temp_folder a global variable
def select_pdf_file(): global temp_folder, current_index file_path = filedialog.askopenfilename(filetypes=[("PDF Files", "*.pdf")]) if file_path: pdf_file = fitz.open(file_path) current_index = 0 temp_folder = tempfile.TemporaryDirectory() image_index = 0 for page in pdf_file: for xref, *_ in page.get_images(): # extract the image info = pdf_file.extract_image(xref) image = PIL.Image.open(io.BytesIO(info ["image"])) #<- Why not put this in a list?? image_file = os.path.join(temp_folder.name, f"image{image_index}.{info ["ext"]}") image.save(os.path.join(temp_folder.name, image_file)) show_image(temp_folder.name, image_file) image_index += 1Making temp_folder a global variable means the temporary folder stays alive until you reassign the temp_folder variable (no reference->delete folder), exit the program, or call the cleanup() function (temp_folder.cleanup()).
One last thing, this does not belong inside select_pdf_file()
def on_key_press(event): global current_index if event.keysym == "Right": current_index = (current_index + 1) % len(image_files) pil_image = PIL.Image.open(os.path.join(temp_folder, image_files[current_index])) tk_image = ImageTk.PhotoImage(pil_image) image_label.config(image=tk_image) elif event.keysym == "Left": current_index = (current_index - 1) % len(image_files) pil_image = PIL.Image.open(os.path.join(temp_folder, image_files[current_index])) tk_image = ImageTk.PhotoImage(pil_image) image_label.config(image=tk_image) root.bind("<Key>", on_key_press)You can embed a function inside another function, but you should only do this with "helper" functions, or if you are making a closure. I don't think either applies in this case.