1+ import os
2+ import tkinter as tk
3+ from tkinter import filedialog , messagebox
4+ from PIL import Image
5+ from pillow_heif import register_heif_opener # Modern HEIC support
6+ from datetime import datetime
7+ import threading
8+
9+ # Register HEIF opener with Pillow
10+ register_heif_opener ()
11+
12+ class ImageToPDFConverterV2 :
13+ def __init__ (self , root ):
14+ self .root = root
15+ self .root .title ("High-Fidelity Converter V2 (WebP & HEIC Support)" )
16+ self .root .geometry ("500x300" )
17+
18+ # Define supported extensions
19+ self .supported_formats = [
20+ ("All Supported Images" , "*.jpg *.jpeg *.png *.bmp *.webp *.heic" ),
21+ ("JPEG" , "*.jpg;*.jpeg" ),
22+ ("PNG" , "*.png" ),
23+ ("WebP" , "*.webp" ),
24+ ("HEIC" , "*.heic" ),
25+ ("BMP" , "*.bmp" )
26+ ]
27+
28+ self .label = tk .Label (root , text = "Select images to convert to PDF" , font = ("Arial" , 12 ))
29+ self .label .pack (pady = 20 )
30+
31+ self .btn_select = tk .Button (root , text = "Select & Convert Images" , command = self .start_conversion , bg = "#4CAF50" , fg = "white" , padx = 20 , pady = 10 )
32+ self .btn_select .pack (pady = 10 )
33+
34+ self .status_label = tk .Label (root , text = "Ready" , fg = "blue" )
35+ self .status_label .pack (pady = 10 )
36+
37+ def start_conversion (self ):
38+ files = filedialog .askopenfilenames (title = "Select Images" , filetypes = self .supported_formats )
39+ if not files :
40+ return
41+
42+ # Run conversion in a separate thread to keep UI responsive
43+ threading .Thread (target = self .process_images , args = (files ,), daemon = True ).start ()
44+
45+ def process_images (self , files ):
46+ try :
47+ timestamp = datetime .now ().strftime ("%Y%m%d_%H%M%S" )
48+ output_folder = f"Converted_PDFs_{ timestamp } "
49+ os .makedirs (output_folder , exist_ok = True )
50+
51+ log_file = os .path .join (output_folder , "conversion_log.txt" )
52+
53+ with open (log_file , "w" ) as log :
54+ log .write (f"Conversion Session: { timestamp } \n " + "=" * 30 + "\n " )
55+
56+ for file_path in files :
57+ file_name = os .path .basename (file_path )
58+ name_wo_ext = os .path .splitext (file_name )[0 ]
59+
60+ self .status_label .config (text = f"Processing: { file_name } ..." )
61+
62+ # Open and convert
63+ img = Image .open (file_path )
64+ img_rgb = img .convert ("RGB" )
65+
66+ pdf_path = os .path .join (output_folder , f"{ name_wo_ext } .pdf" )
67+ # Save with high quality (300 DPI)
68+ img_rgb .save (pdf_path , "PDF" , resolution = 300.0 )
69+
70+ log .write (f"SUCCESS: { file_name } -> { name_wo_ext } .pdf\n " )
71+
72+ self .status_label .config (text = "Status: All Conversions Complete!" , fg = "green" )
73+ messagebox .showinfo ("Success" , f"Converted { len (files )} files!\n Saved in: { output_folder } " )
74+
75+ except Exception as e :
76+ self .status_label .config (text = "Status: Error Occurred" , fg = "red" )
77+ messagebox .showerror ("Error" , f"An error occurred: { str (e )} " )
78+
79+ if __name__ == "__main__" :
80+ root = tk .Tk ()
81+ app = ImageToPDFConverterV2 (root )
82+ root .mainloop ()
0 commit comments