ساخت برنامه کاهش حجم تصاویر با پایتون

پروژه‌های پردازش تصویر

ابزارها ۶ دقیقه مطالعه
فهرست مطالب
این مطلب از سایت tool.hamidvalad.ir گرفته شده است

مقدمه و معرفی کتابخانه‌ها

در دنیای امروز، مدیریت تصاویر و کاهش حجم آنها یکی از چالش‌های روزمره کاربران و برنامه‌نویسان است. تصور کنید که می‌خواهید مجموعه‌ای از تصاویر را برای انتشار در شبکه‌های اجتماعی، وبسایت یا پروژه‌های شخصی آماده کنید. یکی از مشکلات رایج این است که فایل‌های تصویری معمولاً حجم بالایی دارند و مستقیم استفاده از آنها باعث کندی بارگذاری و مصرف بیش از حد فضای ذخیره‌سازی می‌شود. ابزارهای آنلاین بسیاری برای کاهش حجم تصاویر وجود دارد، اما این ابزارها محدودیت‌هایی دارند. برخی از آنها کیفیت تصویر را کاهش می‌دهند، برخی دیگر واترمارک اضافه می‌کنند و بعضی دیگر نیازمند اتصال اینترنت هستند. در چنین شرایطی، داشتن یک اپلیکیشن شخصی و سبک برای کاهش حجم تصاویر، که قابلیت پیش‌نمایش و ذخیره سریع داشته باشد، بسیار کاربردی خواهد بود.

برای ایجاد چنین اپلیکیشنی با پایتون، چند کتابخانه اصلی مورد نیاز است که ترکیب آن‌ها باعث می‌شود برنامه هم کاربرپسند و هم کاربردی باشد. اولین کتابخانه مورد نیاز CustomTkinter است. این کتابخانه نسخه‌ای مدرن از Tkinter است و امکانات بیشتری برای ساخت رابط کاربری جذاب، دکمه‌های شیک و نمایش حالت تاریک یا روشن فراهم می‌کند. با استفاده از CustomTkinter، می‌توان رابطی طراحی کرد که جذاب، ساده و کاربرپسند باشد و تجربه کاربری خوبی ارائه دهد. این موضوع مخصوصاً برای کاربران نهایی که با برنامه سر و کار دارند اهمیت بالایی دارد، زیرا ظاهر زیبا و طراحی منطقی باعث می‌شود استفاده از برنامه راحت‌تر و سریع‌تر انجام شود.

کتابخانه بعدی Pillow یا PIL است. این کتابخانه استاندارد و قدرتمند برای پردازش تصاویر در پایتون محسوب می‌شود. با Pillow می‌توان تصاویر را باز کرد، اندازه آنها را تغییر داد، پیش‌نمایش ایجاد کرد و آنها را در فرمت‌های مختلف ذخیره نمود. همچنین از این کتابخانه می‌توان برای بهبود کیفیت کاهش اندازه تصاویر استفاده کرد. استفاده از فیلترهای بهینه مانند LANCZOS باعث می‌شود کاهش اندازه تصویر با کمترین افت کیفیت انجام شود و نتیجه نهایی طبیعی و با وضوح بالا باشد.

کتابخانه سوم مورد نیاز filedialog از Tkinter است. این کتابخانه به برنامه اجازه می‌دهد تا پنجره‌ای برای انتخاب فایل توسط کاربر باز کند و مسیر تصویر را دریافت کند. استفاده از filedialog باعث می‌شود کاربران بتوانند به راحتی هر تصویری را از سیستم خود انتخاب کنند، بدون نیاز به وارد کردن مسیر به صورت دستی. این ویژگی تجربه کاربری را ساده‌تر و بهینه‌تر می‌کند و برنامه را قابل استفاده برای هر کاربری می‌سازد.

در نهایت، ترکیب این سه کتابخانه باعث می‌شود برنامه‌ای بسازیم که نه تنها قادر به کاهش حجم تصویر است، بلکه رابط کاربری مدرن، پیش‌نمایش تصویر و امکان ذخیره سریع تصویر را نیز ارائه می‌دهد. با این رویکرد، مشکل کاهش حجم تصاویر به صورت ساده و کاربردی حل می‌شود و کاربر می‌تواند تصاویر مورد نظر خود را با چند کلیک آماده استفاده کند. علاوه بر این، این اپلیکیشن قابل توسعه است و می‌توان ویژگی‌های بیشتری مانند پردازش دسته‌ای، انتخاب کیفیت و فرمت خروجی، و حتی drag & drop فایل‌ها را به آن اضافه کرد.

با توجه به اهمیت کاهش حجم تصاویر در سرعت بارگذاری و مصرف حافظه، یادگیری نحوه استفاده از این کتابخانه‌ها و ایجاد چنین اپلیکیشن‌هایی یک مهارت کاربردی برای برنامه‌نویسان و افرادی است که می‌خواهند ابزارهای خود را شخصی‌سازی کنند. این برنامه نه تنها یک پروژه آموزشی مفید است، بلکه یک ابزار واقعی و کاربردی محسوب می‌شود که می‌تواند در پروژه‌های مختلف استفاده شود.

کد اصلی

import customtkinter as ctk
from tkinter import filedialog
from PIL import Image, ImageTk
import os

ctk.set_appearance_mode("dark")
ctk.set_default_color_theme("blue")


class ImageResizerApp(ctk.CTk):
    def __init__(self):
        super().__init__()

        self.title("Image Resizer - Fatemeh")
        self.geometry("600x700")

        self.original_image = None
        self.resized_image = None

        self.label_title = ctk.CTkLabel(self, text="انتخاب عکس", font=("IRANSans", 20))
        self.label_title.pack(pady=10)

        self.btn_browse = ctk.CTkButton(self, text="باز کردن عکس", command=self.open_image)
        self.btn_browse.pack(pady=10)

        self.image_label = ctk.CTkLabel(self, text="")
        self.image_label.pack(pady=10)

        self.status_label = ctk.CTkLabel(self, text="", font=("IRANSans", 14))
        self.status_label.pack(pady=5)

        self.label_options = ctk.CTkLabel(self, text="اندازه خروجی:", font=("IRANSans", 18))
        self.label_options.pack(pady=10)

        self.btn_small = ctk.CTkButton(self, text="کوچیک (50%)", command=lambda: self.resize_image(0.5))
        self.btn_medium = ctk.CTkButton(self, text="متوسط (70%)", command=lambda: self.resize_image(0.7))
        self.btn_large = ctk.CTkButton(self, text="بزرگ (90%)", command=lambda: self.resize_image(0.9))

        self.btn_small.pack(pady=5)
        self.btn_medium.pack(pady=5)
        self.btn_large.pack(pady=5)

        self.btn_save = ctk.CTkButton(self, text="ذخیره تصویر", command=self.save_image, state="disabled")
        self.btn_save.pack(pady=20)

    def open_image(self):
        file_path = filedialog.askopenfilename(
            filetypes=[("Image Files", "*.jpg *.png *.jpeg *.webp")]
        )
        if file_path:
            self.original_image = Image.open(file_path)
            self.show_preview(self.original_image)
            self.status_label.configure(text="")

    def resize_image(self, scale):
        if self.original_image is None:
            return
        
        w, h = self.original_image.size
        new_size = (int(w * scale), int(h * scale))

        self.resized_image = self.original_image.resize(new_size, Image.LANCZOS)
        self.show_preview(self.resized_image)

        self.btn_save.configure(state="normal")

        selected_percent = int(scale * 100)

        self.status_label.configure(
            text=f"✔ حجم موردنظر کم شد — مقدار انتخاب‌شده: {selected_percent}%\nبرای ذخیره روی دکمه «ذخیره تصویر» بزنید."
        )

    def show_preview(self, img):
        preview = img.copy()
        preview.thumbnail((400, 400))

        self.tk_img = ImageTk.PhotoImage(preview)
        self.image_label.configure(image=self.tk_img)

    def save_image(self):
        if self.resized_image:
            save_path = os.path.join(os.getcwd(), "resized_image.jpg")
            self.resized_image.save(save_path)
            
            self.status_label.configure(
                text=f"✔ تصویر ذخیره شد!\nمسیر: {save_path}"
            )


if __name__ == "__main__":
    app = ImageResizerApp()
    app.mainloop()

نکات مهم کد

ساختار کلاس‌محور:
کد در یک کلاس (ImageResizerApp) نوشته شده که باعث سازماندهی بهتر، خوانایی و امکان توسعه آسان می‌شود. این ساختار به برنامه اجازه می‌دهد تمام عناصر رابط کاربری، دکمه‌ها و منطق تغییر اندازه را در یک محل مدیریت کند. کلاس‌ها در پایتون یکی از روش‌های استاندارد برای ایجاد برنامه‌های GUI پیچیده هستند.

استفاده از CustomTkinter:
CustomTkinter یک نسخه مدرن از Tkinter است و امکانات بیشتری برای طراحی رابط کاربری جذاب ارائه می‌دهد. در این برنامه از آن برای ایجاد دکمه‌ها، لیبل‌ها و مدیریت ظاهر کلی اپلیکیشن استفاده شده است. ظاهر تاریک (dark mode) و تم رنگی blue باعث شده اپلیکیشن تجربه کاربری بهتری داشته باشد.

استفاده از Pillow:
کتابخانه Pillow وظیفه باز کردن تصاویر، تغییر اندازه و ساخت پیش‌نمایش را بر عهده دارد. برای تغییر اندازه از فیلتر LANCZOS استفاده شده که کیفیت تصویر کاهش یافته را به حداقل ممکن می‌رساند. همچنین از متد thumbnail برای نمایش پیش‌نمایش استفاده شده تا سرعت برنامه حفظ شود و حجم پیش‌نمایش سبک باشد.

پیام پایین تصویر:
پس از انتخاب هر اندازه (50٪، 70٪، 90٪)، پیام به روز می‌شود و مقدار انتخاب شده را نشان می‌دهد. این پیام به کاربر اطلاع می‌دهد که تصویر آماده ذخیره است و تجربه کاربری را بهبود می‌بخشد.

ذخیره تصویر:
تصویر خروجی بدون نیاز به انتخاب مسیر ذخیره، در همان مسیر برنامه ذخیره می‌شود. این کار باعث سادگی بیشتر و کاهش پیچیدگی برای کاربر نهایی می‌شود.

دکمه‌های فعال/غیرفعال:
دکمه ذخیره فقط زمانی فعال می‌شود که تصویر تغییر اندازه داده شده باشد. این طراحی باعث جلوگیری از خطاهای احتمالی و افزایش تجربه کاربری امن می‌شود.

نتیجه‌گیری

با استفاده از این اپلیکیشن ساده، می‌توان به راحتی تصاویر را بدون افت کیفیت قابل توجه، کاهش حجم داد. این برنامه نمونه‌ای از ترکیب کاربردی CustomTkinter و Pillow است که هم آموزشی و هم عملی می‌باشد. به کمک آن می‌توان پروژه‌های واقعی و کاربردی ساخت، تصاویر را برای وبسایت‌ها و شبکه‌های اجتماعی آماده کرد و تجربه کاربری روان و لذت‌بخش فراهم نمود.

علاوه بر این، این اپلیکیشن قابلیت توسعه دارد و می‌توان ویژگی‌هایی مانند پردازش دسته‌ای تصاویر، انتخاب فرمت خروجی، drag & drop فایل‌ها و گزینه‌های پیشرفته‌تر برای کیفیت تصویر را به آن اضافه کرد. این نوع پروژه‌ها هم مهارت برنامه‌نویسی را تقویت می‌کنند و هم ابزار مفیدی برای استفاده روزمره در کارهای گرافیکی و پروژه‌های وب ایجاد می‌کنند.