3 Star 0 Fork 0

lzq1357 / Modifying pictures

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
DrawFrame.py 13.05 KB
一键复制 编辑 原始数据 按行查看 历史
lzq1357 提交于 2021-07-26 23:15 . UI优化补充
"""
绘制图形
在已有图像上,绘制几何图形、文本,铅笔画任意形状。或绘制新的图像。
(1)直线:鼠标在图像上点击选取或输入坐标得到起点、终点,连接成直线。可设置颜色、宽度等。
(2)矩形:绘制矩形并能够设置颜色、尺寸。(尽量使用鼠标操作)
(3)圆形:绘制实心圆/空心圆(尽量做到可以使用鼠标操作)
(4)文本:添加文本(尽量做到可以使用鼠标操作)
(5)任意形状:使用铅笔绘图。
# ylyy #
"""
from tkinter import *
from tkinter import colorchooser
from PIL import Image, ImageDraw, ImageFont
import UI
from VariableFrame import VariableFrame
#
class DrawFrame(VariableFrame):
x = 0
y = 0
x0 = 0
y0 = 0
inText = None #绘制文字时,输入的字符串
FillColor = "#0000ff"
OutlineColor = "#ff0000"
LineWidth = 6
def __init__(self, canv, master=None):
VariableFrame.__init__(self, canv, master)
bcolor = UI.bg
fcolor = UI.fg
w = UI.rightWidth-12
h = 25
f = UI.font
fy = 5
dy = h+8
fx = 0
sx = 130
i=0
fillLabel = Label(self, bg=self.FillColor,
bitmap=UI.viewBmp, compound='left',
width=h-3, height=h-3)
fillBtn = Button(self, text="填充颜色",
bg=bcolor, fg=fcolor,
bitmap=UI.viewBmp, compound='left',
width=int(w/2)-h, height=h,
font=f,
command=lambda:self.setFillColor(fillLabel))
fillBtn.place(x=fx, y=fy+i*dy)
fillLabel.place(x=sx-20, y=fy+i*dy+3)
LineWidthScale = Scale(self,
from_=0, # 设置最小值
to=50, # 设置最大值
resolution=1, # 设置步距值
orient=HORIZONTAL, # 设置水平方向
label="边框宽度",
bg=bcolor, fg=fcolor,
font=f,
command=self.setLineWidth)
LineWidthScale.set(6)
LineWidthScale.place(x=sx+10, y=fy+i*dy)
i += 1
OutlineLabel = Label(self, bg=self.OutlineColor,
bitmap=UI.viewBmp, compound='left',
width=h-3, height=h-3)
OutlineBtn = Button(self, text="边框颜色",
bg=bcolor, fg=fcolor,
bitmap=UI.viewBmp, compound='left',
width=int(w/2)-h, height=h,
font=f,
command=lambda:self.setOutlineColor(OutlineLabel))
OutlineBtn.place(x=fx, y=fy+i*dy)
OutlineLabel.place(x=sx-20, y=fy+i*dy)
i += 2
rectangleBtn = Button(self, text="矩形",
bg=bcolor, fg=fcolor,
bitmap=UI.viewBmp, compound='left',
width=w, height=h,
font=f,
command=lambda: self.rectangle())
rectangleBtn.place(x=fx, y=fy+i*dy)
i += 1
circleBtn = Button(self, text="椭圆",
bg=bcolor, fg=fcolor,
bitmap=UI.viewBmp, compound='left',
width=w, height=h,
font=f,
command=lambda: self.ellipse())
circleBtn.place(x=fx, y=fy+i*dy)
i += 1
lineBtn = Button(self, text="直线",
bg=bcolor, fg=fcolor,
bitmap=UI.viewBmp, compound='left',
width=w, height=h,
font=f,
command=lambda: self.startLine())
lineBtn.place(x=fx, y=fy+i*dy)
i += 1
pencilBtn = Button(self, text="铅笔",
bg=bcolor, fg=fcolor,
bitmap=UI.viewBmp, compound='left',
width=w, height=h,
font=f,
command=lambda:self.startDraw())
pencilBtn.place(x=fx, y=fy+i*dy)
i += 1
linelaber3 = Label(self, text='输入文字:',
bg=bcolor, fg=fcolor,
bitmap=UI.viewBmp, compound='left',
width=int(w/2), height=h,
font=f) #仅支持英语与数字
linelaber3.place(x=fx, y=fy+i*dy+3)
linetextwrite = Entry(self,
width=int(w/2),
font=f)
linetextwrite.place(x=sx, y=fy+i*dy+3)
i+=1
writeBtn = Button(self, text="输入文本后点击屏幕确认位置",
bg=bcolor, fg=fcolor,
bitmap=UI.viewBmp, compound='left',
width=w, height=h,
font=f,
command=lambda:self.write(linetextwrite.get()))
writeBtn.place(x=fx, y=fy+i*dy)
def press(self,event):
"""
鼠标按下事件,记录坐标
"""
xx, yy = self.canv.getCoord()
ex,ey = self.canv.realCoord(event.x, event.y)
self.x = ex - xx
self.y = ey - yy
def startLine(self):
"""
为绘制直线,绑定事件
"""
self.canv.unbind("<B1-Motion>")
self.canv.bind("<ButtonPress-1>", self.press)
self.canv.bind("<B1-Motion>", self.setLine)
self.canv.bind("<ButtonRelease-1>", self.drawLine)
def setLine(self, event):
"""
鼠标移动事件,设置直线的方向、长度
"""
xx, yy = self.canv.getCoord()
ex,ey = self.canv.realCoord(event.x, event.y)
self.canv.delete("line")
self.canv.create_line((self.x+xx, self.y+yy, ex, ey),
fill=self.FillColor,
width=self.LineWidth,
tags=("line"))
#
def drawLine(self, event):
"""
鼠标释放事件,删除画布上的直线,在图像上绘制直线
"""
xx, yy = self.canv.getCoord()
ex,ey = self.canv.realCoord(event.x, event.y)
self.canv.delete("line")
img = self.canv.img.copy()
draw = ImageDraw.Draw(img)
x1 = int(self.x/self.canv.scale)
y1 = int(self.y/self.canv.scale)
x2 = int((ex-xx)/self.canv.scale)
y2 = int((ey-yy)/self.canv.scale)
draw.line((x1, y1, x2, y2),
fill=self.FillColor,
width=int(self.LineWidth/self.canv.scale))
self.canv.refresh(img)
def rectangle(self):
"""
为绘制矩形,绑定事件
"""
self.canv.unbind("<B1-Motion>")
self.canv.bind("<ButtonPress-1>", self.press)
self.canv.bind("<B1-Motion>", self.setRectangle)
self.canv.bind("<ButtonRelease-1>", self.drawRectangle)
def setRectangle(self, event):
"""
鼠标移动事件,设置矩形的形状、尺寸
"""
xx, yy = self.canv.getCoord()
ex,ey = self.canv.realCoord(event.x, event.y)
self.canv.delete("rectangle")
self.canv.create_rectangle((self.x+xx, self.y+yy, ex, ey),
fill=self.FillColor,
outline=self.OutlineColor,
width=self.LineWidth,
tags=("rectangle"))
#
def drawRectangle(self,event):
"""
鼠标释放事件,删除画布上的矩形,在图像上绘制矩形
"""
xx, yy = self.canv.getCoord()
ex,ey = self.canv.realCoord(event.x, event.y)
x1 = int(self.x/self.canv.scale)
y1 = int(self.y/self.canv.scale)
x2 = int((ex-xx)/self.canv.scale)
y2 = int((ey-yy)/self.canv.scale)
self.canv.delete("rectangle")
img_rectangle = self.canv.img
draw = ImageDraw.Draw(img_rectangle)
draw.rectangle((x1, y1, x2, y2),
outline=self.OutlineColor,
fill=self.FillColor,
width=int(self.LineWidth/self.canv.scale))
self.canv.refresh(img_rectangle)
def write(self, text):
"""
为绘制文本绑定事件
"""
self.canv.unbind("<B1-Motion>")
self.canv.bind("<ButtonRelease-1>", self.drawText)
self.inText = text
def drawText(self, event):
"""
鼠标释放事件,在图像上绘制文本
"""
xx, yy = self.canv.getCoord()
ex,ey = self.canv.realCoord(event.x, event.y)
x1 = int((ex-xx)/self.canv.scale)
y1 = int((ey-yy)/self.canv.scale)
img_write = self.canv.img
draw = ImageDraw.Draw(img_write)
ft = ImageFont.truetype("C:\\WINDOWS\\Fonts\\simkai.TTF", self.LineWidth+6, encoding="utf-8")
draw.text((x1, y1), self.inText, fill=self.FillColor, font=ft)
self.canv.refresh(img_write)
def startDraw(self):
"""
点击绘图的按钮,为鼠标左键绑定绘图用到的函数
"""
self.canv.bind("<ButtonPress-1>", self.press)
self.canv.bind("<B1-Motion>", self.drawing)
self.canv.bind("<ButtonRelease-1>", self.endDraw)
def drawing(self,event):
"""
在画布和图像上,同步绘图,
暂时不更新展示图像,画布上的笔迹用于暂时展示
"""
xx, yy = self.canv.getCoord()
ex,ey = self.canv.realCoord(event.x, event.y)
x1 = int(self.x/self.canv.scale)
y1 = int(self.y/self.canv.scale)
x2 = int((ex-xx)/self.canv.scale)
y2 = int((ey-yy)/self.canv.scale)
draw = ImageDraw.Draw(self.canv.img)
self.canv.create_line(self.x+xx, self.y+yy, ex, ey,
width=self.LineWidth,
fill=self.FillColor,
tags=("pencil"))
draw.line((x1, y1, x2, y2),
width=int(self.LineWidth/self.canv.scale),
fill=self.FillColor)
self.x = ex - xx
self.y = ey - yy
def endDraw(self, event):
"""
一个笔画结束,释放鼠标左键,
删除画布上的笔迹,显示有笔迹的图像
"""
self.canv.delete("pencil")
self.canv.refresh(self.canv.img)
def ellipse(self):
"""
为绘制椭圆,绑定事件
"""
self.canv.unbind("<B1-Motion>")
self.canv.bind("<ButtonPress-1>", self.press)
self.canv.bind("<B1-Motion>", self.setEllipse)
self.canv.bind("<ButtonRelease-1>", self.drawEllipse)
def setEllipse(self, event):
"""
鼠标移动事件,设置椭圆形状、尺寸
"""
xx, yy = self.canv.getCoord()
ex,ey = self.canv.realCoord(event.x, event.y)
self.canv.delete("ellipse")
self.canv.create_oval((self.x+xx, self.y+yy, ex, ey),
fill=self.FillColor,
outline=self.OutlineColor,
width=self.LineWidth,
tags=("ellipse"))
#
def drawEllipse(self, event):
"""
鼠标释放事件,删除画布上的椭圆,在图像上绘制椭圆
"""
xx, yy = self.canv.getCoord()
ex,ey = self.canv.realCoord(event.x, event.y)
x1 = int(self.x/self.canv.scale)
y1 = int(self.y/self.canv.scale)
x2 = int((ex-xx)/self.canv.scale)
y2 = int((ey-yy)/self.canv.scale)
self.canv.delete("ellipse")
img_circle = self.canv.img
draw = ImageDraw.Draw(img_circle)
draw.ellipse((x1, y1, x2, y2),
outline=self.OutlineColor,
fill=self.FillColor,
width=int(self.LineWidth/self.canv.scale))
self.canv.refresh(img_circle)
def setFillColor(self, label):
"""
设置填充颜色,矩形、椭圆、直线、铅笔用到
"""
colorDialog = colorchooser.Chooser(self.master)
rgb,str = colorDialog.show()
self.FillColor = str
if str is None:
str = label.master["bg"]
label["bg"] = str
def setOutlineColor(self, label):
"""
设置线条宽度,矩形、椭圆、直线、铅笔用到
"""
colorDialog = colorchooser.Chooser(self.master)
rgb,str = colorDialog.show()
self.OutlineColor = str
if str is None:
str = label.master["bg"]
label["bg"] = str
def setLineWidth(self, scaleVar):
"""
Scale回调函数,设置线条宽度
"""
self.LineWidth = int(scaleVar)
Python
1
https://gitee.com/lzq1357/Modifying-pictures.git
git@gitee.com:lzq1357/Modifying-pictures.git
lzq1357
Modifying-pictures
Modifying pictures
master

搜索帮助