import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
from rembg import remove
import io
class BackgroundRemoverApp:
def __init__(self, root):
self.root = root
self.root.title("Advanced Background Remover")
self.root.geometry("1200x600")
# Create GUI elements
self.create_widgets()
def create_widgets(self):
# Frame for controls
control_frame = tk.Frame(self.root)
control_frame.pack(pady=10)
# Open file button
open_btn = tk.Button(control_frame, text="Open Image", command=self.open_image)
open_btn.pack(side=tk.LEFT, padx=5)
# Process button
process_btn = tk.Button(control_frame, text="Remove Background", command=self.process_image)
process_btn.pack(side=tk.LEFT, padx=5)
# Save button
save_btn = tk.Button(control_frame, text="Save Result", command=self.save_image)
save_btn.pack(side=tk.LEFT, padx=5)
# Image display frames
image_frame = tk.Frame(self.root)
image_frame.pack(expand=True, fill=tk.BOTH)
self.original_frame = tk.Label(image_frame)
self.original_frame.pack(side=tk.LEFT, expand=True, fill=tk.BOTH, padx=10, pady=10)
self.result_frame = tk.Label(image_frame)
self.result_frame.pack(side=tk.RIGHT, expand=True, fill=tk.BOTH, padx=10, pady=10)
# Status label
self.status = tk.Label(self.root, text="Open an image to begin", bd=1, relief=tk.SUNKEN, anchor=tk.W)
self.status.pack(fill=tk.X)
def open_image(self):
file_path = filedialog.askopenfilename(
filetypes=[("Image files", "*.jpg *.jpeg *.png *.bmp *.webp")]
)
if file_path:
try:
# Open with PIL first to handle more formats
self.original_pil_image = Image.open(file_path)
self.display_image(self.original_pil_image, self.original_frame)
self.status.config(text=f"Loaded: {file_path}")
except Exception as e:
messagebox.showerror("Error", f"Could not load image: {e}")
def process_image(self):
if not hasattr(self, 'original_pil_image'):
messagebox.showwarning("Warning", "Please open an image first")
return
try:
# Convert PIL Image to bytes for rembg
img_bytes = io.BytesIO()
self.original_pil_image.save(img_bytes, format='PNG')
img_bytes = img_bytes.getvalue()
# Remove background using rembg
output_bytes = remove(img_bytes)
# Convert back to PIL Image
self.result_pil_image = Image.open(io.BytesIO(output_bytes))
# Display result
self.display_image(self.result_pil_image, self.result_frame)
self.status.config(text="Background removed successfully")
except Exception as e:
messagebox.showerror("Error", f"Background removal failed: {e}")
def save_image(self):
if not hasattr(self, 'result_pil_image'):
messagebox.showwarning("Warning", "No processed image to save")
return
file_path = filedialog.asksaveasfilename(
defaultextension=".png",
filetypes=[("PNG files", "*.png"), ("All files", "*.*")]
)
if file_path:
try:
self.result_pil_image.save(file_path)
self.status.config(text=f"Image saved to: {file_path}")
except Exception as e:
messagebox.showerror("Error", f"Could not save image: {e}")
def display_image(self, image, frame):
# Resize if too large (while maintaining aspect ratio)
max_width = 550
max_height = 550
width, height = image.size
ratio = min(max_width/width, max_height/height)
if ratio < 1:
new_size = (int(width * ratio), int(height * ratio))
image = image.resize(new_size, Image.LANCZOS)
# Convert to Tkinter format
img_tk = ImageTk.PhotoImage(image)
# Update the display
frame.config(image=img_tk)
frame.image = img_tk # Keep a reference
if __name__ == "__main__":
root = tk.Tk()
app = BackgroundRemoverApp(root)
root.mainloop()