一、什麼是圖像編輯器
圖像編輯器是一種用於修改和增強圖像的軟件工具,在數字化時代中,圖像編輯器越來越重要。
通過使用圖像編輯器軟件,我們可以對圖像進行剪切、旋轉、色彩調整、濾鏡添加、文字添加等操作,讓我們更好的表達和傳遞信息。
二、為什麼使用 Tkinter
在 Python 中,有很多 GUI 工具包可供使用,如 Qt、wxPython 等,但是,Tkinter 是 Python 默認內置的,因此使用 Tkinter 不需要安裝任何額外的庫。
Tkinter 是一個功能強大、簡單易用、跨平台的 GUI 工具包,它支持不同平台的標準 GUI 工具。
雖然 Tkinter 本身可能顯得有些陳舊,但是它非常靈活,可以應用於許多應用程序的開發。
三、圖像編輯器開發思路
我們想要開發的圖像編輯器需要具備以下幾個基本功能:
- 打開、保存圖片
- 縮放、旋轉圖片
- 添加文字
- 添加濾鏡和邊框
四、打開、保存圖片
使用 Tkinter 自帶的組件,我們可以輕鬆創建一個文件選擇對話框,使用 Pillow 庫讀取和保存圖片,如下:
from tkinter import filedialog from PIL import Image, ImageTk def open_image(): file_path = filedialog.askopenfilename() image = Image.open(file_path) photo = ImageTk.PhotoImage(image) canvas.create_image(0, 0, image=photo, anchor='nw') canvas.image = photo def save_image(): file_path = filedialog.asksaveasfilename(defaultextension='.jpg') image = Image.frombytes('RGB', canvas.size(), canvas.postscript(colormode='color')) image.save(file_path)
五、縮放、旋轉圖片
我們可以使用 Tkinter 中的 Canvas 組件來顯示圖片,並使用鼠標滾動事件實現縮放功能,使用鼠標拖動事件實現旋轉功能。
from math import cos, sin def scale(delta): x, y = canvas.canvasx(event.x), canvas.canvasy(event.y) s = delta/120 if image_id: canvas.scale(image_id, x, y, s, s) def rotate(event): global angle x, y = canvas.canvasx(event.x), canvas.canvasy(event.y) if image_id: angle += 5 angle %= 360 rad = angle/180 * pi c, s = cos(rad), sin(rad) canvas.coords(image_id, *rotate_points(x, y, c, s)) def rotate_points(x, y, c, s): xr = x-c*x+s*y yr = y-s*x+c*y return xr-50, yr-50, xr+50, yr-50, xr+50, yr+50, xr-50, yr+50
六、添加文字
我們可以使用 Tkinter 自帶的 Text 組件和 Canvas 組件來添加文字,使用鼠標點擊事件添加文字,並可以使用右鍵菜單修改文字字體和大小。
from tkinter import font, Menu class Textbox: def __init__(self, x, y): self.text = tk.Text(canvas, height=1, font='TkDefaultFont 12', bd=0, highlightthickness=0) self.text.insert('0.0', 'Text') self.text.focus_set() self.text.bind('', self.submit) self.id = canvas.create_window(x, y, window=self.text, anchor='nw') def submit(self, event): text = self.text.get('1.0', 'end-1c') canvas.delete(self.id) self.draw_text(event, text) def draw_text(self, event, text): x, y = canvas.canvasx(event.x), canvas.canvasy(event.y) font_name = font.nametofont('TkDefaultFont').actual()['family'] font_size = font.nametofont('TkDefaultFont').actual()['size'] canvas.create_text(x, y, text=text, font=(font_name, font_size), tags='text') def font_setting(): tag = canvas.gettags(canvas.find_withtag('current'))[0] if tag == 'text': font_size = font.nametofont('TkDefaultFont').actual()['size'] new_size = simpledialog.askinteger('大小', '輸入新字號', initialvalue=font_size) font.nametofont('TkDefaultFont').configure(size=new_size)
七、添加濾鏡和邊框
使用 Pillow 庫中的 ImageFilter 可以添加圖像濾鏡,使用 ImageOps 可以添加圖像邊框。
from PIL import ImageFilter, ImageOps def add_filter(): global image image = image.filter(ImageFilter.CONTOUR) photo = ImageTk.PhotoImage(image) canvas.create_image(0, 0, image=photo, anchor='nw') canvas.image = photo def add_border(): global image image = ImageOps.expand(image, border=20, fill='white') photo = ImageTk.PhotoImage(image) canvas.create_image(0, 0, image=photo, anchor='nw') canvas.image = photo
八、完整代碼示例
下面是一個完整的圖像編輯器代碼示例:
from tkinter import * from tkinter import filedialog, simpledialog, font from PIL import Image, ImageTk, ImageFilter, ImageOps from math import cos, sin, pi root = Tk() root.title('Image Editor') canvas = Canvas(root, bg='white') canvas.pack(fill=BOTH, expand=True) image = None angle = 0 image_id = None def open_image(): global image, image_id file_path = filedialog.askopenfilename() image = Image.open(file_path) photo = ImageTk.PhotoImage(image) canvas.create_image(0, 0, image=photo, anchor='nw') canvas.image = photo image_id = canvas.find_withtag('image')[0] def save_image(): file_path = filedialog.asksaveasfilename(defaultextension='.jpg') image = Image.frombytes('RGB', canvas.size(), canvas.postscript(colormode='color')) image.save(file_path) def scale(delta): x, y = canvas.canvasx(event.x), canvas.canvasy(event.y) s = delta/120 if image_id: canvas.scale(image_id, x, y, s, s) def rotate(event): global angle x, y = canvas.canvasx(event.x), canvas.canvasy(event.y) if image_id: angle += 5 angle %= 360 rad = angle/180 * pi c, s = cos(rad), sin(rad) canvas.coords(image_id, *rotate_points(x, y, c, s)) def rotate_points(x, y, c, s): xr = x-c*x+s*y yr = y-s*x+c*y return xr-50, yr-50, xr+50, yr-50, xr+50, yr+50, xr-50, yr+50 def add_filter(): global image image = image.filter(ImageFilter.CONTOUR) photo = ImageTk.PhotoImage(image) canvas.create_image(0, 0, image=photo, anchor='nw') canvas.image = photo def add_border(): global image image = ImageOps.expand(image, border=20, fill='white') photo = ImageTk.PhotoImage(image) canvas.create_image(0, 0, image=photo, anchor='nw') canvas.image = photo class Textbox: def __init__(self, x, y): self.text = Text(canvas, height=1, font='TkDefaultFont 12', bd=0, highlightthickness=0) self.text.insert('0.0', 'Text') self.text.focus_set() self.text.bind('', self.submit) self.id = canvas.create_window(x, y, window=self.text, anchor='nw') def submit(self, event): text = self.text.get('1.0', 'end-1c') canvas.delete(self.id) self.draw_text(event, text) def draw_text(self, event, text): x, y = canvas.canvasx(event.x), canvas.canvasy(event.y) font_name = font.nametofont('TkDefaultFont').actual()['family'] font_size = font.nametofont('TkDefaultFont').actual()['size'] canvas.create_text(x, y, text=text, font=(font_name, font_size), tags='text') def font_setting(): tag = canvas.gettags(canvas.find_withtag('current'))[0] if tag == 'text': font_size = font.nametofont('TkDefaultFont').actual()['size'] new_size = simpledialog.askinteger('大小', '輸入新字號', initialvalue=font_size) font.nametofont('TkDefaultFont').configure(size=new_size) menu = Menu(root) root.config(menu=menu) file_menu = Menu(menu, tearoff=0) menu.add_cascade(label="文件", menu=file_menu) file_menu.add_command(label="打開", command=open_image) file_menu.add_command(label="保存", command=save_image) edit_menu = Menu(menu, tearoff=0) menu.add_cascade(label="編輯", menu=edit_menu) edit_menu.add_command(label="濾鏡", command=add_filter) edit_menu.add_command(label="添加邊框", command=add_border) text_menu = Menu(menu, tearoff=0) menu.add_cascade(label="文本", menu=text_menu) text_menu.add_command(label="添加文字", command=lambda: Textbox(event.x, event.y)) text_menu.add_command(label="修改字體", command=font_setting) canvas.bind("", rotate) canvas.bind("", lambda event : scale(-120)) canvas.bind("", lambda event : scale(120)) root.mainloop()
原創文章,作者:GSQS,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/133906.html