一、什么是图像编辑器
图像编辑器是一种用于修改和增强图像的软件工具,在数字化时代中,图像编辑器越来越重要。
通过使用图像编辑器软件,我们可以对图像进行剪切、旋转、色彩调整、滤镜添加、文字添加等操作,让我们更好的表达和传递信息。
二、为什么使用 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/n/133906.html
微信扫一扫
支付宝扫一扫