با این ابزار ساده اما مفیدی که می توانید خودتان بسازید، همه چیز را در مورد مدیریت تصویر در پایتون بیاموزید.
کولاژ روشی زیبا برای نمایش خاطرات و نمایش مجموعه ای از تصاویر است. سازندگان کلاژ آنلاین ممکن است نگرانی های امنیتی داشته باشند و برنامه های آفلاین ممکن است هزینه داشته باشند و ویژگی های مورد نیاز شما را نداشته باشند.
با ساختن سازنده کلاژ تصویر خود می توانید این نگرانی ها را از بین ببرید و کنترل کامل را حفظ کنید. بنابراین، چگونه می توانید یکی بسازید؟
ماژول Tkinter و PIL
برای ساختن یک برنامه کولاژ تصویر به Tkinter و ماژول PIL نیاز دارید. Tkinter به شما اجازه می دهد تا برنامه های دسکتاپ ایجاد کنید. ویجت های مختلفی را ارائه می دهد که توسعه رابط کاربری گرافیکی را آسان تر می کند.
کتابخانه Pillow – یک شاخه کتابخانه تصویربرداری پایتون (PIL) – قابلیتهای پردازش تصویر را ارائه میکند که به ویرایش، ایجاد، تبدیل فرمتهای فایل و ذخیره تصاویر کمک میکند.
برای نصب Tkinter و Pillow، یک ترمینال را باز کنید و اجرا کنید:
pip install tk pillow
راه اندازی رابط کاربری گرافیکی و دستکاری تصویر
شما می توانید کد منبع این پروژه را در مخزن GitHub آن پیدا کنید.
با وارد کردن ماژول های مورد نیاز شروع کنید. یک کلاس ایجاد کنید، ImageCollageApp، و عنوان و ابعاد پنجره را تنظیم کنید. بوم را با استفاده از ()tk.Canvas تعریف کنید و عنصر اصلی، عرض، ارتفاع و رنگ پسزمینه آن را تنظیم کنید.
import tkinter as tk
from tkinter import filedialog, simpledialog, messagebox
from PIL import Image, ImageTk
class ImageCollageApp:
def __init__(self, root):
self.root = root
self.root.title("Image Collage Maker")
self.images = []
self.image_refs = []
self.collage_size = (600, 500)
self.collage_canvas = tk.Canvas(
self.root,
width=self.collage_size[0],
height=self.collage_size[1],
bg="white",
)
self.collage_canvas.pack()
دو دکمه ایجاد کنید: افزودن تصویر و ایجاد کلاژ. عنصر والد، متن برای نمایش، دستور اجرا و سبک های فونت را تعریف کنید. با افزودن بالشتک مناسب، دکمه ها را سازماندهی کنید. برای ذخیره اطلاعات مربوط به عملیات کشیدن، drag_data را راه اندازی کنید.
برای ذخیره موقعیت های تصاویر روی بوم، image_positions را مقداردهی کنید. سه کنترل کننده رویداد را برای پاسخ به انتخاب، کشیدن و انتشار تصاویر تعریف کنید.
self.btn_add_image = tk.Button(
self.root,
text="Add Image",
command=self.add_images,
font=("Arial", 12, "bold"),
)
self.btn_add_image.pack(pady=10)
self.btn_create_collage = tk.Button(
self.root,
text="Create Collage",
command=self.create_collage,
font=("Arial", 12, "bold"),
)
self.btn_create_collage.pack(pady=5)
self.drag_data = {"x": 0, "y": 0, "item": None}
self.image_positions = []
self.collage_canvas.bind("<ButtonPress-1>", self.on_press)
self.collage_canvas.bind("<B1-Motion>", self.on_drag)
self.collage_canvas.bind("<ButtonRelease-1>", self.on_release)
یک روش تعریف کنید، on_press. نزدیکترین مورد بوم را از محلی که کاربر روی ماوس کلیک میکند بازیابی کنید و آن را در زیر کلید مورد فرهنگ لغت drag_data ذخیره کنید. مختصات x و y کلیک ماوس را ذخیره کنید. شما از این برای محاسبه فاصله حرکت ماوس توسط کاربر در حین کشیدن استفاده خواهید کرد.
def on_press(self, event):
self.drag_data["item"] = self.collage_canvas.find_closest(event.x, event.y)[0]
self.drag_data["x"] = event.x
self.drag_data["y"] = event.y
یک متد تعریف کنید، on_drag. فاصله افقی و عمودی را که کاربر در حین کشیدن ماوس حرکت داده است محاسبه کنید و موقعیت تصویر را متناسب با آن به روز کنید. مختصات به روز شده تصویر را در زیر کلیدهای x و y فرهنگ لغت drag_data ذخیره کنید.
def on_drag(self, event):
delta_x = event.x - self.drag_data["x"]
delta_y = event.y - self.drag_data["y"]
self.collage_canvas.move(self.drag_data["item"], delta_x, delta_y)
self.drag_data["x"] = event.x
self.drag_data["y"] = event.y
یک روش تعریف کنید، on_release. ارجاع به تصویری را که کاربر می کشید همراه با مختصات آن پاک کنید. برای به روز رسانی موقعیت همه تصاویر روی بوم پس از کشیدن و رها کردن آن توسط کاربر، update_image_positions را فراخوانی کنید.
def on_release(self, event):
self.drag_data["item"] = None
self.drag_data["x"] = 0
self.drag_data["y"] = 0
self.update_image_positions()
یک متد، update_image_positions تعریف کنید. لیست image_positions را پاک کنید و روی همه موارد بوم تکرار کنید. برای هر مورد، مختصات را پیدا کرده و به لیست اضافه کنید.
def update_image_positions(self):
self.image_positions.clear()
for item in self.collage_canvas.find_all():
x, y = self.collage_canvas.coords(item)
self.image_positions.append((x, y))
یک متد تعریف کنید، add_images. یک کادر محاوره ای ایجاد کنید که از کاربر می خواهد تعداد تصاویر کلاژ را وارد کند. اگر کاربر یک شماره معتبر ارائه کرده است، کادر محاوره ای فایلی را باز کنید که فقط به کاربر اجازه می دهد فایل های تصویری را انتخاب کند. هنگامی که کاربر یک یا چند تصویر را انتخاب کرد، هر کدام را با متد Pillow’s Image.open() باز کنید.
متد resize_image را فراخوانی کنید و یک PhotoImage سازگار با Tkinter ایجاد کنید. این را به لیست image_refs اضافه کنید و متد update_canvas را فراخوانی کنید.
def add_images(self):
num_images = simpledialog.askinteger(
"Number of Images", "Enter the number of images:"
)
if num_images is not None:
file_paths = filedialog.askopenfilenames(
filetypes=[("Image files", "*.png;*.jpg;*.jpeg;*.gif")]
)
if file_paths:
for i in range(min(num_images, len(file_paths))):
file_path = file_paths[i]
image = Image.open(file_path)
resized_image = self.resize_image(image)
self.images.append(resized_image)
self.image_refs.append(ImageTk.PhotoImage(resized_image))
self.update_canvas()
یک متد تعریف کنید، resize_image. عرض و ارتفاع تصویر را بدست آورید و نسبت تصویر آن را محاسبه کنید. اگر بیشتر از یک است، عرض جدید را نصف عرض کلاژ تنظیم کنید. ارتفاع جدید مربوطه را با حفظ نسبت ابعاد محاسبه کنید.
اگر نسبت تصویر کمتر از یک باشد، ارتفاع جدید را نیمی از ارتفاع کلاژ قرار دهید. به طور مشابه، عرض مربوطه را محاسبه کنید. از روش تغییر اندازه Pillow برای برگرداندن یک تصویر تغییر اندازه با استفاده از پارامترهای محاسبه شده استفاده کنید.
def resize_image(self, image):
img_width, img_height = image.size
aspect_ratio = img_width / img_height
if aspect_ratio > 1:
new_width = self.collage_size[0] // 2
new_height = int(new_width / aspect_ratio)
else:
new_height = self.collage_size[1] // 2
new_width = int(new_height * aspect_ratio)
return image.resize((new_width, new_height))
یک متد تعریف کنید update_canvas. تمام موارد را پاک کنید و از طریق یک کادر محاوره ای فایل، تعداد سطر و ستون مورد نظر را از کاربر بخواهید. عرض و ارتفاع کلاژ را به اندازه نیمی از اندازه کلاژ مشخص شده تنظیم کنید. لیست موقعیت های تصویر را پاک می کند. افست x و y را به صفر مقداردهی کنید، بنابراین می توانید موقعیت جابجایی را برای مرتب کردن تصاویر در ردیف ها و ستون ها پیگیری کنید.
def update_canvas(self):
self.collage_canvas.delete("all")
rows = simpledialog.askinteger("Number of Rows", "Enter the number of rows:")
cols = simpledialog.askinteger(
"Number of Columns", "Enter the number of columns:"
)
collage_width = self.collage_size[0] * cols // 2
collage_height = self.collage_size[1] * rows // 2
self.collage_canvas.config(width=collage_width, height=collage_height)
self.image_positions.clear()
x_offset, y_offset = 0, 0
روی لیست image_refs تکرار کنید و با استفاده از افست مشخص شده یک تصویر روی بوم ایجاد کنید. لنگر را روی شمال غربی قرار دهید تا گوشه سمت چپ بالای تصویر را در مختصات مشخص شده قرار دهید. این مختصات را به لیست image_positions اضافه کنید.
x_offset را به روز کنید تا نیمی از عرض کلاژ را اضافه کنید تا برای قرار دادن تصویر بعدی آماده شوید. اگر تعداد تصاویر قرار داده شده در ردیف فعلی مضربی از تعداد مشخص شده ستون باشد، x_offset را صفر کنید. این نشان دهنده شروع یک ردیف جدید است. نیمی از ارتفاع کلاژ را اضافه کنید تا مختصات y را برای ردیف بعدی تنظیم کنید.
for i, image_ref in enumerate(self.image_refs):
self.collage_canvas.create_image(
x_offset, y_offset, anchor=tk.NW, image=image_ref
)
self.image_positions.append((x_offset, y_offset))
x_offset += self.collage_size[0] // 2
if (i + 1) % cols == 0:
x_offset = 0
y_offset += self.collage_size[1] // 2
ایجاد کلاژ و ذخیره آن
یک متد تعریف کنید create_collage. اگر هیچ تصویری روی کلاژ وجود ندارد، یک هشدار نمایش دهید. عرض و ارتفاع کلاژ را جمع آوری کنید. یک تصویر بالش با پس زمینه سفید ایجاد کنید. لیست تصاویر را تکرار کنید و هر تصویر را در پس زمینه در موقعیت های مشخص شده قرار دهید.
کلاژ را ذخیره کرده و با استفاده از نمایشگر تصویر پیش فرض نمایش دهید.
def create_collage(self):
if len(self.images) == 0:
messagebox.showwarning("Warning", "Please add images first!")
return
collage_width = self.collage_canvas.winfo_width()
collage_height = self.collage_canvas.winfo_height()
background = Image.new("RGB", (collage_width, collage_height), "white")
for idx, image in enumerate(self.images):
x_offset, y_offset = self.image_positions[idx]
x_offset, y_offset = int(x_offset), int(y_offset)
paste_box = (
x_offset,
y_offset,
x_offset + image.width,
y_offset + image.height,
)
background.paste(image, paste_box)
background.save("collage_with_white_background.jpg")
background.show()
یک نمونه از کلاس Tkinter و ImageCollage App ایجاد کنید. تابع mainloop() به پایتون می گوید که حلقه رویداد Tkinter را اجرا کند و تا زمانی که پنجره را ببندید به رویدادها گوش دهد.
if __name__ == "__main__":
root = tk.Tk()
app = ImageCollageApp(root)
root.mainloop()
تست ویژگی های مختلف Image Collage Maker
هنگام اجرای برنامه، پنجره ای با دو دکمه Add Image و Create Collage ظاهر می شود. با کلیک بر روی دکمه افزودن تصویر، یک کادر محاوره ای تعداد تصاویر برای کلاژ را می پرسد. با وارد کردن تعداد تصاویر به عنوان پنج و انتخاب آنها، کادر محاوره ای دیگری ظاهر می شود. تعداد سطرها و به دنبال آن تعداد ستون ها را می پرسد.
با وارد کردن دو سطر و سه ستون، پنجره تصاویر را در یک ساختار شبکه ای سازماندهی می کند.
پیش نمایش به شما امکان می دهد تصاویر را به دلخواه بکشید. با کلیک بر روی دکمه Create Collage، برنامه تصویر را ذخیره می کند.
با مشاهده تصویر، می توانید تأیید کنید که برنامه با موفقیت کلاژ را ایجاد کرده است.
بهبود عملکرد تصویر کلاژ ساز
به جای یک قالب جدولی، می توانید الگوهای پیش فرض مختلفی را برای انتخاب کاربر ارائه دهید. ویژگی هایی برای تغییر رنگ پس زمینه، افزودن متن، اعمال فیلتر روی تصاویر و درج برچسب از اینترنت اضافه کنید.
در حین افزودن این ویژگیها، ویرایش کلاژ را با گزینهای برای لغو یا انجام مجدد آسان کنید. به کاربر اجازه برش دادن، تغییر اندازه و ورق زدن تصاویر را بر اساس میل خود بدهید. همچنین باید گزینه ای برای ذخیره تصویر در فرمت دلخواه خود اضافه کنید.