一、什麼是圖像編輯器
圖像編輯器是一種用於修改和增強圖像的軟件工具,在數字化時代中,圖像編輯器越來越重要。
通過使用圖像編輯器軟件,我們可以對圖像進行剪切、旋轉、色彩調整、濾鏡添加、文字添加等操作,讓我們更好的表達和傳遞信息。
二、為什麼使用 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
微信掃一掃
支付寶掃一掃