Last active
May 12, 2025 13:55
-
-
Save DraconicDragon/0c2726d9dfc622d22cce48e315109c84 to your computer and use it in GitHub Desktop.
This is better https://gist.github.com/DraconicDragon/a00740bcb6dc54070b48c69a141b1c62 | A PNG to JPG converter that preserves the EXIF metadata (mainly to convert AI generated images to save storage space)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import os | |
| import tkinter as tk | |
| from tkinter import filedialog | |
| import piexif | |
| import piexif.helper | |
| from PIL import Image | |
| class PNGtoJPGConverterApp: | |
| def __init__(self, master): | |
| self.master = master | |
| self.master.title("PNG to JPG Converter") | |
| self.src_path = tk.StringVar() | |
| self.dst_path = tk.StringVar() | |
| # Create labels and entry fields for source and destination paths | |
| tk.Label(master, text="Source Path:").grid(row=0, column=0) | |
| self.src_entry = tk.Entry(master, textvariable=self.src_path) | |
| self.src_entry.grid(row=0, column=1) | |
| tk.Button(master, text="Browse", command=self.browse_src_path).grid(row=0, column=2) | |
| tk.Label(master, text="Destination Path:").grid(row=1, column=0) | |
| self.dst_entry = tk.Entry(master, textvariable=self.dst_path) | |
| self.dst_entry.grid(row=1, column=1) | |
| tk.Button(master, text="Browse", command=self.browse_dst_path).grid(row=1, column=2) | |
| tk.Button(master, text="Convert", command=self.convert).grid(row=2, column=1, pady=10) | |
| def browse_src_path(self): | |
| path = filedialog.askdirectory() | |
| if path: | |
| self.src_path.set(path) | |
| def browse_dst_path(self): | |
| path = filedialog.askdirectory() | |
| if path: | |
| self.dst_path.set(path) | |
| def convert(self): | |
| src_path = self.src_path.get() | |
| dst_path = os.path.join(src_path, "jpg") | |
| os.makedirs(dst_path, exist_ok=True) | |
| def convertPNGtoJPG(path): | |
| image = Image.open(os.path.join(src_path, path)) | |
| items = image.info or {} | |
| geninfo = items.pop("parameters", None) | |
| if "exif" in items: | |
| exif = piexif.load(items["exif"]) | |
| exif_comment = (exif or {}).get("Exif", {}).get(piexif.ExifIFD.UserComment, b"") | |
| try: | |
| exif_comment = piexif.helper.UserComment.load(exif_comment) | |
| except ValueError: | |
| exif_comment = exif_comment.decode("utf8", errors="ignore") | |
| if exif_comment: | |
| items["exif comment"] = exif_comment | |
| geninfo = exif_comment | |
| for field in [ | |
| "jfif", | |
| "jfif_version", | |
| "jfif_unit", | |
| "jfif_density", | |
| "dpi", | |
| "exif", | |
| "loop", | |
| "background", | |
| "timestamp", | |
| "duration", | |
| ]: | |
| items.pop(field, None) | |
| jpg = image.convert("RGB") | |
| exif_bytes = piexif.dump( | |
| { | |
| "Exif": { | |
| piexif.ExifIFD.UserComment: piexif.helper.UserComment.dump( | |
| geninfo or "", encoding="unicode" | |
| ) | |
| }, | |
| } | |
| ) | |
| pre, ext = os.path.splitext(path) | |
| dstpath = os.path.join(dst_path, pre + ".jpg") | |
| jpg.save(dstpath, quality=99) | |
| piexif.insert(exif_bytes, dstpath) | |
| print(dstpath) | |
| # Iterate directory | |
| for path in os.listdir(src_path): | |
| # check if current path is a file | |
| if path.endswith("png") and os.path.isfile(os.path.join(src_path, path)): | |
| convertPNGtoJPG(path) | |
| root = tk.Tk() | |
| app = PNGtoJPGConverterApp(root) | |
| root.mainloop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment