3 Star 0 Fork 0

lzq1357 / Modifying pictures

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
IconFrame.py 9.74 KB
一键复制 编辑 原始数据 按行查看 历史
lzq1357 提交于 2021-08-07 22:40 . PdfFrame & 一些优化
"""
添加图标:添加图标形状,眼镜、帽子、蝴蝶结等等。(可以设置图标大小)。
# lzq #
"""
from tkinter import *
from tkinter import filedialog
import os
from PIL import Image,ImageTk
import UI
from VariableFrame import VariableFrame
#
class IconFrame(VariableFrame):
canv=None
icon={} #保存图标相关信息
imgtk=[] #保存要显示的图像,避免函数结束,图像被销毁
path="icon\\"
start={} #鼠标移动的起始坐标
iconCanvas = None
def __init__(self, canv, master=None):
VariableFrame.__init__(self, canv, master)
bcolor = UI.bg
fcolor = UI.fg
pw = UI.rightWidth-12
ph = 25
f = UI.font
chooseBtn = Button(self, text="选择文件",
bg=bcolor, fg=fcolor,
bitmap=UI.viewBmp, compound='left',
width=pw, height=ph,
font=f,
command=lambda: self.chooseFile())
chooseBtn.pack(side=TOP, fill=X, ipadx="3p", ipady="3p", padx="2p", pady="2p", expand=1)
self.iconCanvas = Canvas(self,bg=UI.bg,width=230,scrollregion=(0,0,240,3000))
vbar = Scrollbar(self,orient=VERTICAL)
vbar.pack(side=RIGHT,fill=Y)
vbar.config(command=self.iconCanvas.yview)
self.iconCanvas.config(width=240,height=605)
self.iconCanvas.config(yscrollcommand=vbar.set)
self.iconCanvas.pack(side=TOP)
self.icon["setsize"] = (ImageTk.PhotoImage(Image.open("img\\setsize.png").resize((20,20))))
self.icon["confirm"] = (ImageTk.PhotoImage(Image.open("img\\confirm.png").resize((20,20))))
self.icon["delete"] = (ImageTk.PhotoImage(Image.open("img\\delete.png").resize((20,20))))
self.showIcon()
def onSizeChanged(self, width, height):
self.iconCanvas.configure(height=height)
pass
def showIcon(self):
"""
在IconFrame中展示图标,供用户选择
"""
files=os.listdir(self.path)
i=0
for f in files:
f=self.path+f
img=Image.open(f)
img = img.resize((100,100))
imgtk = ImageTk.PhotoImage(img)
self.imgtk.append(imgtk)
lb=Label(self,image=imgtk,width=100,height=100,text=f)
lb.bind("<Double-Button-1>", self.onDoubleClick)
self.iconCanvas.create_window((15+i%2*115,20+i//2*120),
window=lb,
anchor=NW)
i+=1
self.iconCanvas["scrollregion"] = (0, 0, 300, 20+i//2*120)
def chooseFile(self):
"""
选择图标文件
"""
types = [('image files', '*.jpg *.jpeg *.png *.gif *.webp'), ('all files', '*.*')]
file_path = filedialog.askopenfilename(filetypes=types)
if not os.path.isfile(file_path):
return
self.chooseIcon(file_path)
def onDoubleClick(self, event):
"""
双击IconFrame中的图标时发生,通过画布显示图标,等待用户设置位置和尺寸
(没有直接添加在图像上)
"""
path=event.widget["text"]
self.chooseIcon(path)
def chooseIcon(self, path):
canv=self.canv
icon = Image.open(path)
self.icon["path"]=path
self.icon["img"]=icon
self.display(icon)
canv.tag_bind("icon", "<ButtonPress-1>", self.recordStart)
canv.tag_bind("img", "<B1-Motion>", self.move)
canv.tag_bind("confirm", "<Button-1>", self.confirm)
canv.tag_bind("setsize", "<B1-Motion>", self.setSize)
canv.tag_bind("setsize", "<ButtonRelease-1>", self.release)
canv.tag_bind("delete", "<Button-1>", self.delete)
def display(self, icon):
"""
显示图标,及辅助元素
"""
w = icon.width
h = icon.height
ww = (self.canv.width-10)/w
hh = (self.canv.height-10)/h
if ww<1 or hh<1:
if ww<hh:
min=ww
else:
min=hh
w = int(w*min)
h = int(h*min)
self.icon["width"] = w
self.icon["height"] = h
self.icon["imgtk"] = ImageTk.PhotoImage(icon.resize((w,h)))
x = (self.canv.width-w)/2
y = (self.canv.height-h)/2
x,y = self.canv.realCoord(x, y)
self.canv.create_image(x, y,
image=self.icon["imgtk"],
anchor=NW,
tags=("icon", "img"))
self.canv.create_rectangle(x, y, x+w, y+h,
width=3,
outline="#ee88aa",
tags=("icon", "rect"))
self.drawSign(x, y, w, h)
imgx,imgy = self.canv.getCoord()
self.icon["x"] = x-imgx
self.icon["y"] = y-imgy
#
def drawSign(self, x, y, w, h):
"""
绘制delete, confirm, setsize标志
"""
canv=self.canv
canv.create_image(x-10, y-10,
image=self.icon["delete"],
anchor=NW,
tags=("icon","delete"))
canv.create_image(x+w-10, y-10,
image=self.icon["confirm"],
anchor=NW,
tags=("icon","confirm"))
canv.create_image(x+w-10, y+h-10,
image=self.icon["setsize"],
anchor=NW,
tags=("icon","setsize"))
#
def addIcon(self, img, icon, icon_x, icon_y):
"""
将图标icon添加在图像img上
"""
w=icon.width
h=icon.height
ww=img.width
hh=img.height
img_seq=list(img.getdata())
icon_seq=list(icon.getdata())
bands_num = len(img.getbands())
for i in range(w*h):
r,g,b,a=icon_seq[i]
if a>0:
x=i%w+icon_x
y=i//w+icon_y
if x>=0 and x<ww and y>=0 and y<hh:
if bands_num == 4:
img_seq[y * ww + x] = (r, g, b, a)
elif bands_num == 3:
r0,g0,b0 = img_seq[y*ww+x]
img_seq[y*ww+x] = self.rgba2rgb(r,g,b,a, r0,g0,b0)
elif bands_num == 1:
img_seq[y*ww+x] = self.rgba2gray(r,g,b,a,img_seq[y*ww+x])
img.putdata(img_seq)
def move(self, event):
"""
鼠标拖拽移动图标位置
"""
endX,endY = self.canv.realCoord(event.x, event.y)
self.canv.move("icon", endX-self.start["x"], endY-self.start["y"])
self.icon["x"] += endX-self.start["x"]
self.icon["y"] += endY-self.start["y"]
self.start["x"] = endX
self.start["y"] = endY
#print(self.icon["x"], self.icon["y"])
def recordStart(self, event):
"""
鼠标按下,记录鼠标位置
"""
x,y = self.canv.realCoord(event.x, event.y)
self.start["x"] = x
self.start["y"] = y
def confirm(self, event):
"""
设置好图标参数后,确认添加
"""
icon = Image.open(self.icon["path"])
w = int(self.icon["width"]/self.canv.scale)
h = int(self.icon["height"]/self.canv.scale)
icon = icon.resize((w, h))
x = int(self.icon["x"]/self.canv.scale)
y = int(self.icon["y"]/self.canv.scale)
img = self.canv.img.copy()
self.addIcon(img, icon, x, y)
self.canv.refresh(img)
self.canv.delete("icon")
def setSize(self, event):
"""
鼠标拖拽,设置图标尺寸
"""
x,y = self.canv.getCoord()
x += self.icon["x"]
y += self.icon["y"]
ex,ey = self.canv.realCoord(event.x, event.y)
w = int(ex-x)
h = int(ey-y)
self.icon["width"] = w
self.icon["height"] = h
icon = self.icon["img"].resize((w, h))
icontk = ImageTk.PhotoImage(icon)
self.icon["imgtk"] = icontk
self.canv.delete("img")
self.canv.delete("rect")
self.canv.create_image(x, y, image=icontk, anchor=NW,tags=("icon", "img"))
self.canv.create_rectangle(x, y, x+w, y+h, width=3, outline="#ee88aa", tags=("icon", "rect"))
self.canv.coords("setsize",x+w-10, y+h-10)
self.canv.coords("confirm",x+w-10, y-10)
self.start["x"]=ex
self.start["y"]=ey
def delete(self, event):
"""
点击删除标志,从画布上删除图标
"""
self.canv.delete("icon")
def release(self, event):
"""
设置尺寸后释放鼠标左键,重绘delete, confirm, setsize标志
避免被覆盖,鼠标事件失效
"""
x,y = self.canv.getCoord()
x += self.icon["x"]
y += self.icon["y"]
w = self.icon["width"]
h = self.icon["height"]
self.canv.delete("delete")
self.canv.delete("confirm")
self.canv.delete("setsize")
self.drawSign(x, y, w, h)
def rgba2gray(self, r, g, b, a, gray):
"""
系数据说来自心理学
gray为背景
"""
r1,g1,b1 = self.rgba2rgb(r,g,b,a, gray, gray, gray)
gray = (r1*299 + g1*587 + b1*114 + 500) / 1000
return gray
def rgba2rgb(self, r,g,b,a, r0,g0,b0):
"""
r0,g0,b0为背景
"""
m = a/255
r1 = int(r*m + r0*(1-m))
g1 = int(g*m + g0*(1-m))
b1 = int(b*m + b0*(1-m))
return (r1,g1,b1)
pass
#
Python
1
https://gitee.com/lzq1357/Modifying-pictures.git
git@gitee.com:lzq1357/Modifying-pictures.git
lzq1357
Modifying-pictures
Modifying pictures
master

搜索帮助