Contents

如何使用 Python 製作圖像拼貼畫

拼貼畫是展示記憶和展示圖像集的絕佳方式。在線拼貼製作者可能存在安全問題,而離線應用程序可能需要花錢並且缺乏您所需的功能。

人們可以通過構建自己的圖像拼貼創建器來減輕憂慮並保持絕對權威。那麼,如何構建這樣一個工具呢?

Tkinter 和 PIL 模塊

要為圖像拼貼應用程序構建圖形用戶界面,需要同時利用 Tkinter 庫和 Python 圖像庫 (PIL)。前者可以通過提供各種視覺元素或“小部件”來創建基於桌面的應用程序,從而簡化圖形用戶界面 (GUI) 的設計過程。

Pillow 庫是備受推崇的 Python 圖像處理庫 (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”的方法。當用戶在畫布上繪圖時單擊鼠標時會觸發此方法。此方法的目標是檢索距用戶單擊鼠標點最近的畫布對象並將其存儲在“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”變量計算拖動操作期間光標移動的水平和垂直距離。基於這些值,可以通過修改“self.canvas”小部件中“image”對象的“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)) 

當然!下面是一個使用 Tkinter 和 Pillow 庫在 Python 中實現的示例: pythonimport tkinter as tkfrom tkinter import filedialogimport osfrom PIL import Imagedef add_images():# create a new windowwindow=tk.Toplevel(root)# Ask user how much images are not uploadnum_images=tk.Entry(window)num_images.pack()num_entries=tk.Label(window, text=“輸入圖像數量:”)num_entries.pack()# 從條目字段獲取值num_values=num_images.get()if num_values.isdigit() 和int(

利用 resize\_image 函數重新縮放內存中的當前圖像,創建一個新的 Tkinter 兼容的 PhotoImage 。隨後,在使用 update_canvas 方法更新畫布之前,將此更新後的引用附加到 image_refs 列表中。

     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() 

以下是 Python 中 resize_image 方法的示例實現:pythondef resize_image(self, image):# 獲取圖像的當前尺寸img_width, img_height=image.size# 計算圖像的長寬比aspect_ratio=img_height/img_width# 檢查如果寬高比大於1(即縱向)如果aspect_ratio > 1:# 將新寬度設置為拼貼寬度的一半new_width=self.collage_width/2# 在保持寬高比的情況下計算相應的新高度new_height=int ((

如果拼貼畫的長寬比小於1,我們將根據拼貼畫的原始尺寸計算適當的尺寸,將其高度和寬度減半。然後,我們可以利用 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 對象,該對象擁有原始的白色背景。然後,該函數將迭代文件目錄,並使用 Python 強大的 PIL 庫將它們精確地放置在畫布上的預定坐標處,以有效地操作圖像數據。

利用預設圖像查看器通過首先保存來展示數字拼貼畫,利用其內置功能實現最佳可視化。

     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() 

通過實例化 ImageCollage 應用程序的新實例來利用 Tkinter 庫的功能,該實例配備了根據用戶輸入生成視覺拼貼所需的必要屬性和方法。建立後,使用 mainloop() 方法啟動 Tkinter 事件循環的執行。此命令指示 Python 解釋器持續監視和處理窗口內發生的任何事件,有效地維護其狀態,直到最終用戶手動關閉窗口。

 if __name__ == "__main__":
    root = tk.Tk()
    app = ImageCollageApp(root)
    root.mainloop() 

測試圖像拼貼製作器的不同功能

執行應用程序後,將顯示一個具有兩個選項的界面-“添加圖像”和“創建拼貼畫”。單擊“添加圖像”選項後,將出現一個彈出窗口,詢問用戶輸入他們希望包含在拼貼畫中的圖片總數。一旦輸入“5”作為所需的圖像數量並從給定列表中選擇它們,就會出現另一個對話框,請求有關構建拼貼畫時應使用的水平行和垂直列的數量的信息。

/bc/images/start-screen-of-image-collage-application.jpg

在指定的邊界空間內插入兩行和三列的視覺元素後,圖形用戶界面將它們系統地排列為陣列或矩陣配置,創建一個有凝聚力的顯示,強調每個單獨組件的定位和順序。

/bc/images/image-collage-default-preview-for-5-images-in-2-rows-3-columns.jpg

預覽允許根據個人喜好重新定位圖像來操作圖像。單擊“創建拼貼”按鈕後,軟件將保存生成的圖像。

/bc/images/dragging-images-to-desired-positions-within-canvas.jpg

在檢查生成的拼貼畫的視覺表示後,很明顯,該軟件應用程序已經實現了其在組裝有凝聚力且視覺上吸引人的圖像集合方面的預期目標。

/bc/images/desired-collage-image.jpg

增強圖像拼貼製作工具的功能

可以為用戶提供一系列預定義模板以供選擇,而不是使用基於表格的結構。此外,還整合了一些功能,可以改變背景色調、刻寫書面內容、應用圖像增強以及集成來自在線資源的裝飾元素。

在合併這些功能的同時,通過提供撤消或重繪操作的​​選項,啟用一種簡單的方法來修改合成圖像。此外,允許用戶根據自己的喜好調整單個圖像的裁剪、調整大小和方向。此外,還包括一項功能,可以將最終輸出保存為所選文件格式。