Spaces:
Runtime error
Runtime error
| #!/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() | |