วิธีสร้างภาพต่อกันโดยใช้ Python
ภาพต่อกันเป็นวิธีที่สวยงามในการแสดงความทรงจำและแสดงชุดรูปภาพ เครื่องมือสร้างภาพตัดปะออนไลน์อาจมีข้อกังวลด้านความปลอดภัย และแอปออฟไลน์อาจต้องเสียค่าใช้จ่ายและขาดคุณสมบัติที่คุณต้องการ
เราอาจบรรเทาความวิตกกังวลและรักษาอำนาจโดยสมบูรณ์โดยการสร้างโปรแกรมสร้างภาพต่อกันของตนเอง แล้วเราจะสร้างเครื่องมือดังกล่าวได้อย่างไร?
โมดูล Tkinter และ PIL
ในการสร้างอินเทอร์เฟซผู้ใช้แบบกราฟิกสำหรับแอปพลิเคชันภาพตัดปะ จำเป็นต้องใช้ทั้งไลบรารี Tkinter และ Python Imaging Library (PIL) แบบแรกช่วยให้สามารถสร้างแอปพลิเคชันบนเดสก์ท็อปผ่านการจัดเตรียมองค์ประกอบภาพต่างๆ หรือ"วิดเจ็ต"ซึ่งปรับปรุงกระบวนการออกแบบอินเทอร์เฟซผู้ใช้แบบกราฟิก (GUI)
ไลบรารี Pillow ซึ่งเป็นอนุพันธ์ของ Python Imaging Library (PIL) ที่ได้รับการยอมรับอย่างดี นำเสนอฟีเจอร์การจัดการรูปภาพที่หลากหลาย ซึ่งอำนวยความสะดวกให้กับงานต่างๆ เช่น การแก้ไข การสร้าง และการบันทึกไฟล์สื่อภาพประเภทต่างๆ
ในการติดตั้ง Tkinter และ Pillow สามารถเริ่มต้นได้โดยการเปิดอินเทอร์เฟซบรรทัดคำสั่งและดำเนินการคำสั่งต่อไปนี้:
pip install tk pillow
การตั้งค่า GUI และการจัดการรูปภาพ
อาจค้นหาซอร์สโค้ดสำหรับโปรเจ็กต์นี้ภายในพื้นที่เก็บข้อมูล 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()
ตรวจสอบให้แน่ใจว่าผู้ใช้ได้ให้สิทธิ์ในการป้อนข้อมูลไฟล์ก่อนที่จะสร้างออบเจ็กต์ FileReader เพื่ออ่านไฟล์ภาพจากอุปกรณ์ของตน
เริ่มต้นโครงสร้างข้อมูลที่เรียกว่า"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"ก่อน วิธีการนี้จะเกิดขึ้นเมื่อผู้ใช้คลิกเมาส์ขณะวาดภาพบนผืนผ้าใบ เป้าหมายของวิธีนี้คือการดึงออบเจ็กต์ Canvas ที่ใกล้ที่สุดไปยังจุดที่ผู้ใช้คลิกเมาส์และจัดเก็บไว้ในพจนานุกรม"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"ซึ่งจะเริ่มทำงานเมื่อผู้ใช้เลื่อนเมาส์ขณะที่กดปุ่มซ้ายค้างไว้ วิธีนี้จะคำนวณระยะทางแนวนอนและแนวตั้งที่เคอร์เซอร์เคลื่อนที่ระหว่างการลากโดยใช้ตัวแปร"dx"และ"dy"ตามค่าเหล่านี้ ตำแหน่งของรูปภาพสามารถอัปเดตได้โดยการแก้ไขแอตทริบิวต์"x"และ"y"ของออบเจ็กต์"รูปภาพ"ภายในวิดเจ็ต"self.canvas"นอกจากนี้ พิกัดใหม่สำหรับรูปภาพควรเก็บไว้ในพจนานุกรม “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"ที่จัดการกับข้อกังวลเหล่านี้ โดยเฉพาะอย่างยิ่ง วิธีการนี้ควรล้างการอ้างอิงถึงรูปภาพที่มีเคอร์เซอร์ของผู้ใช้มาด้วยในระหว่างการลาก ในขณะเดียวกันก็เรียกใช้ฟังก์ชัน"อัปเดต\_รูปภาพ\_ตำแหน่ง"เพื่อแก้ไขเค้าโครงของรูปภาพที่แสดงทั้งหมดภายหลังจาก การยุติการโต้ตอบของผู้ใช้
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))
แน่นอน! นี่คือตัวอย่างการใช้งานใน Python โดยใช้ Tkinter และ Pillow Library:pythonimport tkinter as tkfrom tkinter import filedialogimport osfrom PIL import Imagedef add_images():# create a new windowwindow=tk.Toplevel(root)# ถามผู้ใช้ว่าต้องการกี่ภาพ uploadnum_images=tk.Entry(window)num_images.pack()num_entries=tk.Label(window, text=“ป้อนจำนวนภาพ:")num_entries.pack()# รับค่าจากรายการ fieldnum_values =num_images.get()if num_values.isdigit() และ int(
ใช้ฟังก์ชัน 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
ใน Python:pythondef resize_image(self, image):# รับขนาดปัจจุบันของ imageimg_width, img_height=image.size# คำนวณอัตราส่วนภาพของ imageaspect_ratio=img_height/img_width# ตรวจสอบ หากอัตราส่วนกว้างยาวมากกว่า 1 (เช่น การวางแนวแนวตั้ง) หากอัตราส่วนภาพ > 1:# ตั้งค่าความกว้างใหม่ให้เป็นครึ่งหนึ่งของ widthnew_width=self.collage_width/2# คำนวณความสูงใหม่ที่สอดคล้องกันในขณะที่ยังคงรักษาอัตราส่วนกว้างยาว new_height=int ((
หากอัตราส่วนภาพของภาพต่อกันน้อยกว่าหนึ่ง เราจะลดทั้งความสูงและความกว้างลงครึ่งหนึ่งโดยการคำนวณขนาดที่เหมาะสมตามขนาดดั้งเดิมของภาพต่อกัน จากนั้นเราสามารถใช้ฟังก์ชัน ปรับขนาด
ของ 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” ด้วยขั้นตอนต่อไปนี้:1. ล้างรายการทั้งหมดบนผืนผ้าใบโดยลบลิงก์ที่คลิกได้ซึ่งเชื่อมโยงกับแต่ละรายการออกจากการจัดเรียงรูปภาพก่อนหน้านี้2. นำเสนอโอกาสให้ผู้ใช้ป้อนจำนวนแถวและคอลัมน์ที่ต้องการผ่านกล่องโต้ตอบไฟล์ ขนาดที่ให้ไว้ควรสอดคล้องกับข้อกำหนดที่ระบุก่อนหน้าในเอกสารนี้3. กำหนดจำนวนคอลัมน์ทั้งหมดที่ต้องการตามจำนวนแถวที่ผู้ใช้ป้อน ในตัวอย่างของเรา เราจะสมมติว่ามีหกคอลัมน์ต่อแถว คำนวณความกว้างและความสูงของภาพตัดปะตามลำดับ ซึ่งหมายความว่าหากผู้ใช้เลือกสี่แถว ความกว้างจะเป็นสองเท่าของความกว้างของหนึ่งคอลัมน์ (6) บวกด้วยระยะขอบของช่องว่างระหว่างแถวเหล่านั้น เพราะเหตุนี้
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
โดยการเพิ่มครึ่งหนึ่งของภาพตัดปะ
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
อัลกอริธึมนี้จะตรวจสอบก่อนว่ามีรายการสื่อใดรวมอยู่ในการเรียบเรียงหรือไม่ หากไม่มีก็จะแสดงข้อความเตือน จากนั้นเทคนิคนี้จะกำหนดขนาดของภาพตัดต่ออิเล็กทรอนิกส์โดยพิจารณาจากความกว้างและความสูง ถัดไป มันจะสร้างออบเจ็กต์ Pillow Image ที่ว่างเปล่าใหม่ซึ่งมีฉากหลังสีขาวบริสุทธิ์ จากนั้น ฟังก์ชันจะวนซ้ำแค็ตตาล็อกของไฟล์และวางไว้อย่างแม่นยำบนผืนผ้าใบตามพิกัดที่กำหนดไว้ล่วงหน้า โดยใช้ไลบรารี PIL อันทรงพลังของ Python เพื่อการจัดการข้อมูลรูปภาพอย่างมีประสิทธิภาพ
ใช้โปรแกรมดูรูปภาพที่กำหนดไว้ล่วงหน้าเพื่อแสดงภาพตัดปะดิจิทัลโดยการบันทึกไว้ก่อน โดยใช้ประโยชน์จากความสามารถในตัวเพื่อการแสดงภาพที่ดีที่สุด
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 ซึ่งมาพร้อมกับคุณลักษณะและวิธีการที่จำเป็นในการสร้างภาพต่อกันตามการป้อนข้อมูลของผู้ใช้ เมื่อสร้างเสร็จแล้ว ให้เริ่มต้นการดำเนินการของลูปเหตุการณ์ Tkinter โดยใช้วิธีการ mainloop() คำสั่งนี้สั่งให้ล่าม Python ตรวจสอบและประมวลผลเหตุการณ์ใด ๆ ที่เกิดขึ้นภายในหน้าต่างอย่างต่อเนื่อง โดยคงสถานะไว้อย่างมีประสิทธิภาพจนกว่าผู้ใช้ปลายทางจะปิดด้วยตนเอง
if __name__ == "__main__":
root = tk.Tk()
app = ImageCollageApp(root)
root.mainloop()
การทดสอบคุณสมบัติต่างๆ ของ Image Collage Maker
เมื่อรันแอปพลิเคชัน อินเทอร์เฟซที่มีสองตัวเลือกจะปรากฏขึ้น-“เพิ่มรูปภาพ"และ"สร้างภาพต่อกัน"เมื่อคลิกที่ตัวเลือก"เพิ่มรูปภาพ"ป๊อปอัปเพื่อสอบถามข้อมูลผู้ใช้สำหรับจำนวนรูปภาพทั้งหมดที่ต้องการรวมไว้ในภาพตัดปะจะปรากฏขึ้น เมื่อป้อน'5’เป็นจำนวนรูปภาพที่ต้องการ และเลือกจากรายการที่กำหนด กล่องโต้ตอบเพิ่มเติมจะปรากฏขึ้นเพื่อขอข้อมูลเกี่ยวกับจำนวนแถวแนวนอนและคอลัมน์แนวตั้งที่ควรใช้ในการสร้างภาพต่อกัน
เมื่อแทรกองค์ประกอบภาพสองแถวและสามคอลัมน์ภายในพื้นที่ขอบเขตที่กำหนด อินเทอร์เฟซผู้ใช้แบบกราฟิกจะจัดเรียงองค์ประกอบเหล่านั้นอย่างเป็นระบบเป็นการกำหนดค่าอาร์เรย์หรือเมทริกซ์ สร้างจอแสดงผลที่สอดคล้องกันซึ่งเน้นตำแหน่งและลำดับของแต่ละองค์ประกอบ
การแสดงตัวอย่างช่วยให้สามารถจัดการรูปภาพได้โดยการเปลี่ยนตำแหน่งใหม่ตามความต้องการ เมื่อคลิกที่ปุ่ม"สร้างภาพต่อกัน"ซอฟต์แวร์จะบันทึกภาพที่ได้
เมื่อตรวจสอบการแสดงภาพของภาพตัดปะที่สร้างขึ้น จะเห็นได้ชัดว่าแอปพลิเคชันซอฟต์แวร์บรรลุวัตถุประสงค์ตามที่ตั้งใจไว้ในส่วนที่เกี่ยวกับการรวบรวมคอลเลกชันรูปภาพที่เหนียวแน่นและดึงดูดสายตา
ปรับปรุงฟังก์ชันการทำงานของ Image Collage Maker
แทนที่จะใช้โครงสร้างแบบตาราง คุณสามารถเสนอตัวเลือกเทมเพลตที่กำหนดไว้ล่วงหน้าให้กับผู้ใช้ได้ นอกจากนี้ ยังรวมฟังก์ชันที่ช่วยให้สามารถเปลี่ยนเฉดสีพื้นหลัง เขียนเนื้อหา ปรับใช้การปรับปรุงรูปภาพ และบูรณาการองค์ประกอบตกแต่งที่ได้มาจากแหล่งข้อมูลออนไลน์
ในขณะที่รวมฟังก์ชันเหล่านี้ไว้ ให้เปิดใช้งานวิธีการที่ตรงไปตรงมาในการแก้ไขภาพคอมโพสิตโดยให้ตัวเลือกสำหรับการยกเลิกหรือการวาดใหม่ นอกจากนี้ อนุญาตให้ผู้ใช้ปรับการครอบตัด การปรับขนาด และการวางแนวของแต่ละภาพได้ตามความต้องการ นอกจากนี้ ยังมีคุณลักษณะที่ช่วยให้สามารถบันทึกเอาต์พุตสุดท้ายในรูปแบบไฟล์ที่เลือกได้