Hur man gör ett bildcollage med Python
Ett collage är ett vackert sätt att visa upp minnen och visa uppsättningar av bilder. Collage-skapare på nätet kan ha säkerhetsproblem och offline-appar kan kosta pengar och sakna de funktioner du behöver.
Man kan minska oron och bibehålla absolut auktoritet genom att konstruera sin helt egen bildcollage-skapare. Men hur gör man för att konstruera ett sådant verktyg?
Tkinter- och PIL-modulen
För att konstruera ett grafiskt användargränssnitt för ett bildcollageprogram måste man använda både Tkinter-biblioteket och Python Imaging Library (PIL). Det förstnämnda gör det möjligt att skapa skrivbordsbaserade applikationer genom att tillhandahålla olika visuella element eller “widgets”, som effektiviserar processen med att utforma grafiska användargränssnitt (GUI).
Pillow-biblioteket, ett derivat av det välrenommerade Python Imaging Library (PIL), erbjuder en rad funktioner för bildhantering som underlättar uppgifter som att redigera, generera och spara olika typer av visuella mediefiler.
Installationen av Tkinter och Pillow kan påbörjas genom att öppna ett kommandoradsgränssnitt och utföra följande kommando:
pip install tk pillow
GUI Setup and Image Manipulation
Man kan hitta källkoden för detta projekt i dess särskilda GitHub-arkiv, som fungerar som ett digitalt arkiv för alla filer och dokumentation som är kopplade till det.
För att kunna börja är det viktigt att importera de nödvändiga modulerna. Därefter ska vi skapa en ny klass med namnet ImageCollageApp
som kommer att fungera som huvudapplikationsobjekt. Det första steget är att ange titel och dimensioner för fönstret. Vi kommer sedan att generera en canvas med hjälp av metoden tk.Canvas()
och konfigurera dess föräldraelement, bredd, höjd och bakgrundsfärg.
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()
Se till att användaren har gett tillstånd för filinmatning innan du skapar ett FileReader-objekt för att läsa bildfiler från deras enhet.
Initiera en datastruktur som heter “image\_positions” för lagring av den visuella positioneringen av mediaelement i det grafiska användargränssnittet. Implementera tre separata händelsehanteringsrutiner för att hantera val, flyttning och frigörande av åtgärder som är associerade med nämnda medieelement.
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)
För att implementera den funktionalitet som beskrivs i det medföljande kodavsnittet måste vi först definiera en metod som heter “on\_press”. Denna metod utlöses när användaren klickar med musen medan han/hon ritar på duken.Målet med den här metoden är att hämta det canvasobjekt som ligger närmast den punkt där användaren klickade med musen och lagra det i ordlistan “drag\_data”. Dessutom kommer vi att lagra X- och Y-koordinaterna för musklicket så att vi senare kan beräkna hur långt användaren har flyttat musen under dragningen.
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
För att implementera den funktionalitet som beskrivs i kodavsnittet är det nödvändigt att definiera en metod som heter “on\_drag” som aktiveras när användaren flyttar musen samtidigt som vänsterknappen hålls nedtryckt. Denna metod beräknar de horisontella och vertikala avstånden som markören har färdats under dragoperationen med hjälp av variablerna “dx” och “dy”. Baserat på dessa värden kan bildens position sedan uppdateras genom att ändra attributen “x” och “y” för objektet “image” i widgeten “self.canvas”. Dessutom bör de nya koordinaterna för bilden lagras i “drag\_data”-ordboken som är associerad med den aktuella instansen av klassen, vilket gör att de kan bevaras över flera bildrutor.
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
För att rensa upp eventuella kvarvarande referenser till den tidigare dragna bilden och räkna om positioneringen av alla visuella element på duken som svar på en release-händelse, kan du implementera en “on\_release”-metod som hanterar dessa problem. Denna metod bör ta bort referensen till den bild som hade åtföljts av användarens markör under dragningen, samtidigt som funktionen “update\_image\_positions” anropas för att revidera layouten för alla visade bilder efter det att användarinteraktionen har upphört.
def on_release(self, event):
self.drag_data["item"] = None
self.drag_data["x"] = 0
self.drag_data["y"] = 0
self.update_image_positions()
På ett elegant sätt ska vi definiera en funktion med titeln “update\_image\_positions”, som innebär att innehållet i “image\_positions”-matrisen raderas och itereras genom varje beståndsdel i duken. Under denna process ska vi för varje komponent identifiera dess positionsdata och lägga till dem i den nämnda matrisen.
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))
Visst! Här är ett exempel på implementering i Python med Tkinter och Pillow-biblioteket:pythonimport tkinter as tkfrom tkinter import filedialogimport osfrom PIL import Imagedef add_images():# skapa ett nytt fönsterwindow = tk.Toplevel(root)# fråga användaren hur många bilder han eller hon vill ladda uppnum_images = tk.Entry(window)num_images.pack()num_entries = tk.Label(window, text=“Ange antal bilder:")num_entries.pack()# hämta värde från postfältetnum_values = num_images.get()if num_values.isdigit() and int(
Använd funktionen resize_image
för att skala om den aktuella bilden i minnet och skapa en ny Tkinter-kompatibel PhotoImage
.Därefter lägger du till den uppdaterade referensen i listan image_refs
innan du uppdaterar duken med metoden 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()
Här är ett exempel på implementering av metoden resize_image
i Python:pythondef resize_image(self, image):# Hämta aktuella dimensioner för bildenimg_width, img_height = image.size# Beräkna bildförhållandet för bildenaspect_ratio = img_height / img_width# Kontrollera om bildförhållandet är större än 1 (t.ex, porträttorientering)if aspect_ratio > 1:# Sätt den nya bredden till hälften av kollagets breddnew_width = self.collage_width / 2# Beräkna motsvarande nya höjd med bibehållet sidförhållandeew_height = int((
Om kollagets sidförhållande är mindre än ett halverar vi både dess höjd och bredd genom att beräkna lämpliga dimensioner baserat på kollagets originalstorlek. Vi kan sedan använda Pillows funktion resize
för att skapa en förstorad version av collaget med de justerade måtten samtidigt som vi behåller dess proportioner.
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))
Definiera en metod med namnet “update\_canvas” med följande steg:1. Rensa alla objekt på duken genom att ta bort deras respektive klickbara länkar som är kopplade till varje objekt från det tidigare arrangemanget av bilder.2. Ge användaren möjlighet att ange önskat antal rader och kolumner via en dialogruta för filer. De mått som anges bör överensstämma med de specifikationer som anges tidigare i detta dokument.3. Bestäm det totala antalet kolumner som krävs baserat på det antal rader som användaren har angett. I vårt exempel antar vi att det finns sex kolumner per rad. Beräkna collagets bredd och höjd i enlighet med detta. Detta innebär att om användaren väljer fyra rader, så blir bredden två gånger bredden på en kolumn (6) plus en marginal mellan dem. Följaktligen
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
Iterera genom varje objekt i listan image_refs
och skapa en visuell representation av det på duken genom att använda den angivna förskjutningen. Placera bildens övre vänstra hörn vid de angivna koordinaterna genom att sätta dess ankarpunkt till det nordvästra hörnet. Lägg dessutom till motsvarande koordinater i listan image_positions
för ytterligare referens.
För att effektivt arrangera den efterföljande bilden i rutnätet är det viktigt att uppdatera variabeln x_offset
genom att lägga till hälften av collaget
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
Skapa collaget och spara det
För att skapa en tilltalande visuell representation av olika digitala tillgångar kommer vi att utveckla en funktion som kallas create_collage
. Denna algoritm kommer först att kontrollera om några mediaobjekt har inkluderats i kompositionen eller inte. Om så inte är fallet visas ett varningsmeddelande. Därefter kommer denna teknik att bestämma dimensionerna på det elektroniska montaget genom att ta reda på dess bredd och statur. Därefter konstrueras ett nytt tomt Pillow Image-objekt som har en vit bakgrund. Därefter itererar funktionen över katalogen med filer och placerar dem exakt på duken vid deras förutbestämda koordinater med hjälp av Pythons kraftfulla PIL-bibliotek för effektiv manipulation av bilddata.
Använd den förinställda bildvisaren för att visa det digitala collaget genom att spara det först och utnyttja dess inbyggda funktioner för optimal visualisering.
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()
Utnyttja funktionerna i Tkinter-biblioteket genom att instansiera en ny instans av programmet ImageCollage, som är utrustat med de nödvändiga attribut och metoder som krävs för att generera visuella collage baserat på användarens input. När den är etablerad, initiera exekveringen av Tkinter event loop med hjälp av mainloop()-metodiken. Detta kommando instruerar Python-tolken att kontinuerligt övervaka och bearbeta alla händelser som inträffar i fönstret, vilket effektivt upprätthåller dess tillstånd tills det stängs manuellt av slutanvändaren.
if __name__ == "__main__":
root = tk.Tk()
app = ImageCollageApp(root)
root.mainloop()
Test av olika funktioner i Image Collage Maker
När programmet körs visas ett gränssnitt med två alternativ - “Lägg till bild” och “Skapa collage”. När du klickar på alternativet “Lägg till bild” visas en popup som frågar användaren om det totala antalet bilder som de vill inkludera i sitt collage. Efter att ha angett “5” som önskat antal bilder och valt dem från den givna listan, visas ytterligare en dialogruta med information om både antalet horisontella rader och vertikala kolumner som ska användas för att konstruera collaget.
När två rader och tre kolumner med visuella element har placerats inom det angivna gränsutrymmet, arrangerar det grafiska användargränssnittet dem systematiskt som en matris, vilket skapar en sammanhängande visning som betonar varje enskild komponents placering och ordning.
I förhandsgranskningen kan du manipulera bilderna genom att flytta dem enligt dina önskemål. När du klickar på knappen “Skapa collage” kommer programmet att spara den resulterande bilden.
När man granskar den visuella representationen av det genererade collaget är det uppenbart att programvaran har uppnått sitt avsedda mål när det gäller att sammanställa en sammanhängande och visuellt tilltalande samling bilder.
Förbättring av bildcollage-skaparens funktionalitet
I stället för att använda en tabellbaserad struktur är det möjligt att erbjuda användarna ett urval av fördefinierade mallar att välja mellan. Införliva dessutom funktioner som gör det möjligt att ändra bakgrundsnyansen, skriva in skriftligt innehåll, använda bildförbättringar och integrera dekorativa element från onlinekällor.
Samtidigt som dessa funktioner införlivas, möjliggörs en enkel metod för att modifiera den sammansatta bilden genom att tillhandahålla alternativ för att ångra eller rita om operationer. Dessutom kan användarna justera beskärning, storlek och orientering av enskilda bilder enligt sina önskemål. Inkludera dessutom en funktion som gör det möjligt att spara slutresultatet i ett valt filformat.