#!/usr/bin/env python3 """ DR-Image-Magic - Simple GUI Version Quick image transformations without database setup """ import tkinter as tk from tkinter import filedialog, messagebox, ttk from PIL import Image, ImageTk, ImageEnhance, ImageFilter import os from pathlib import Path class ImageMagicGUI: def __init__(self, root): self.root = root self.root.title("DR-Image-Magic - Simple GUI") self.root.geometry("1000x850") # Bigger window self.root.configure(bg='#1a1a2e') self.current_image = None self.original_image = None self.image_path = None self.setup_ui() def setup_ui(self): # Title title = tk.Label( self.root, text="🎨 DR-Image-Magic", font=("Arial", 24, "bold"), bg='#1a1a2e', fg='#ff6b35' ) title.pack(pady=20) # Upload Button upload_btn = tk.Button( self.root, text="📁 Upload Image", command=self.upload_image, font=("Arial", 14), bg='#ff6b35', fg='white', padx=20, pady=10, cursor='hand2' ) upload_btn.pack(pady=10) # Image Preview self.image_label = tk.Label( self.root, bg='#16213e', text="No image loaded", fg='#aaa', font=("Arial", 12) ) self.image_label.pack(pady=20, padx=20, fill=tk.BOTH, expand=True) # Effects Frame effects_frame = tk.Frame(self.root, bg='#1a1a2e') effects_frame.pack(pady=10) tk.Label( effects_frame, text="🎨 Effects:", font=("Arial", 14, "bold"), bg='#1a1a2e', fg='#ff6b35' ).grid(row=0, column=0, columnspan=4, pady=10) # Effect Buttons effects = [ ("✨ Enhance", self.enhance_image), ("🌈 Vibrant", self.vibrant_image), ("🌙 Dark & Moody", self.dark_moody), ("☀️ Bright & Warm", self.bright_warm), ("🎭 High Contrast", self.high_contrast), ("🌊 Cool Tones", self.cool_tones), ("🔥 Warm Tones", self.warm_tones), ("📸 Vintage", self.vintage_effect), ("💎 Sharpen", self.sharpen_image), ("🌫️ Blur", self.blur_image), ("🎨 Abstract", self.abstract_effect), ("⚫ Grayscale", self.grayscale_image), ] row = 1 col = 0 for text, command in effects: btn = tk.Button( effects_frame, text=text, command=command, font=("Arial", 10), bg='#0f3460', fg='white', padx=10, pady=5, cursor='hand2' ) btn.grid(row=row, column=col, padx=5, pady=5, sticky='ew') col += 1 if col > 3: col = 0 row += 1 # Action Buttons action_frame = tk.Frame(self.root, bg='#1a1a2e') action_frame.pack(pady=20) reset_btn = tk.Button( action_frame, text="🔄 Reset", command=self.reset_image, font=("Arial", 12), bg='#e94560', fg='white', padx=15, pady=8 ) reset_btn.pack(side=tk.LEFT, padx=10) save_btn = tk.Button( action_frame, text="💾 Save As...", command=self.save_image, font=("Arial", 12), bg='#16a34a', fg='white', padx=15, pady=8 ) save_btn.pack(side=tk.LEFT, padx=10) def upload_image(self): file_path = filedialog.askopenfilename( title="Select an Image", filetypes=[ ("Image Files", "*.png *.jpg *.jpeg *.webp *.bmp"), ("All Files", "*.*") ] ) if file_path: try: self.image_path = file_path self.original_image = Image.open(file_path) self.current_image = self.original_image.copy() self.display_image(self.current_image) except Exception as e: messagebox.showerror("Error", f"Failed to load image: {e}") def display_image(self, image): # Resize for display (max 500x300 to save space for buttons) display_img = image.copy() display_img.thumbnail((500, 300), Image.Resampling.LANCZOS) photo = ImageTk.PhotoImage(display_img) self.image_label.configure(image=photo, text="") self.image_label.image = photo def check_image_loaded(self): if self.current_image is None: messagebox.showwarning("No Image", "Please upload an image first!") return False return True # Effect Methods def enhance_image(self): if not self.check_image_loaded(): return enhancer = ImageEnhance.Contrast(self.current_image) self.current_image = enhancer.enhance(1.3) enhancer = ImageEnhance.Sharpness(self.current_image) self.current_image = enhancer.enhance(1.2) self.display_image(self.current_image) def vibrant_image(self): if not self.check_image_loaded(): return enhancer = ImageEnhance.Color(self.current_image) self.current_image = enhancer.enhance(1.5) self.display_image(self.current_image) def dark_moody(self): if not self.check_image_loaded(): return enhancer = ImageEnhance.Brightness(self.current_image) self.current_image = enhancer.enhance(0.7) enhancer = ImageEnhance.Contrast(self.current_image) self.current_image = enhancer.enhance(1.4) self.display_image(self.current_image) def bright_warm(self): if not self.check_image_loaded(): return enhancer = ImageEnhance.Brightness(self.current_image) self.current_image = enhancer.enhance(1.2) enhancer = ImageEnhance.Color(self.current_image) self.current_image = enhancer.enhance(1.3) self.display_image(self.current_image) def high_contrast(self): if not self.check_image_loaded(): return enhancer = ImageEnhance.Contrast(self.current_image) self.current_image = enhancer.enhance(2.0) self.display_image(self.current_image) def cool_tones(self): if not self.check_image_loaded(): return # Convert to RGB if needed if self.current_image.mode != 'RGB': self.current_image = self.current_image.convert('RGB') # Apply blue tint r, g, b = self.current_image.split() r = r.point(lambda i: i * 0.9) g = g.point(lambda i: i * 0.95) b = b.point(lambda i: i * 1.1) self.current_image = Image.merge('RGB', (r, g, b)) self.display_image(self.current_image) def warm_tones(self): if not self.check_image_loaded(): return # Convert to RGB if needed if self.current_image.mode != 'RGB': self.current_image = self.current_image.convert('RGB') # Apply orange tint r, g, b = self.current_image.split() r = r.point(lambda i: min(255, i * 1.1)) g = g.point(lambda i: i * 1.05) b = b.point(lambda i: i * 0.9) self.current_image = Image.merge('RGB', (r, g, b)) self.display_image(self.current_image) def vintage_effect(self): if not self.check_image_loaded(): return # Sepia effect self.current_image = self.current_image.convert('L') self.current_image = self.current_image.convert('RGB') r, g, b = self.current_image.split() r = r.point(lambda i: min(255, i * 1.2)) g = g.point(lambda i: i * 1.0) b = b.point(lambda i: i * 0.8) self.current_image = Image.merge('RGB', (r, g, b)) enhancer = ImageEnhance.Contrast(self.current_image) self.current_image = enhancer.enhance(0.9) self.display_image(self.current_image) def sharpen_image(self): if not self.check_image_loaded(): return self.current_image = self.current_image.filter(ImageFilter.SHARPEN) self.display_image(self.current_image) def blur_image(self): if not self.check_image_loaded(): return self.current_image = self.current_image.filter(ImageFilter.GaussianBlur(radius=2)) self.display_image(self.current_image) def abstract_effect(self): if not self.check_image_loaded(): return self.current_image = self.current_image.filter(ImageFilter.EDGE_ENHANCE_MORE) enhancer = ImageEnhance.Color(self.current_image) self.current_image = enhancer.enhance(1.8) self.display_image(self.current_image) def grayscale_image(self): if not self.check_image_loaded(): return self.current_image = self.current_image.convert('L').convert('RGB') self.display_image(self.current_image) def reset_image(self): if not self.check_image_loaded(): return self.current_image = self.original_image.copy() self.display_image(self.current_image) def save_image(self): if not self.check_image_loaded(): return file_path = filedialog.asksaveasfilename( defaultextension=".png", filetypes=[ ("PNG", "*.png"), ("JPEG", "*.jpg"), ("WebP", "*.webp"), ("All Files", "*.*") ] ) if file_path: try: self.current_image.save(file_path) messagebox.showinfo("Success", f"Image saved to:\n{file_path}") except Exception as e: messagebox.showerror("Error", f"Failed to save image: {e}") if __name__ == "__main__": root = tk.Tk() app = ImageMagicGUI(root) root.mainloop()