仅供参考,未完善,老铁轻喷
程序包:
https://download.csdn.net/download/wyazyf/87959961
程序包升级版
链接: https://pan.baidu.com/s/1k8GPWPL3xJ2yUXz2XCR5Mg?pwd=6666
代码如下:
import base64
from datetime import datetime
import cv2
import numpy as np
import tkinter as tk
from tkinter import ttk
from tkinter import *
# filedialog函数用于上传文件
from tkinter import filedialog
# 因为头像是图片需要用到pillow库
from PIL import Image, ImageTk
class ImageSize:
def __init__(self):
# 小一寸
self._lt_one_inch_w = 260
self._lt_one_inch_h = 390
self._lt_one_ratio = self._lt_one_inch_w / self._lt_one_inch_h
# 一寸
self._one_inch_w = 295
self._one_inch_h = 413
self._one_ratio = self._one_inch_w / self._one_inch_h
# 小二寸
self._lt_two_inch_w = 390
self._lt_two_inch_h = 567
self._lt_two_ratio = self._lt_two_inch_w / self._lt_two_inch_h
# 二寸
self._two_inch_w = 413
self._two_inch_h = 636
self._two_ratio = self._two_inch_w / self._two_inch_h
# 五寸
self._five_inch_w = 840
self._five_inch_h = 1200
self._five_ratio = self._five_inch_w / self._five_inch_h
# 六寸
self._six_inch_w = 960
self._six_inch_h = 1440
self._six_ratio = self._six_inch_w / self._six_inch_h
# 七寸
self._seven_inch_w = 1680
self._seven_inch_h = 1200
self._seven_ratio = self._seven_inch_w / self._seven_inch_h
# ID card
self._id_inch_w = 358
self._id_inch_h = 441
self._id_ratio = self._id_inch_w / self._id_inch_h
# 图片尺寸
def photo_size(self, img,size):
img = img
h, w = img.shape[:2]
img_ratio = w / h
if size==0:
# 小一寸
if img_ratio >= self._lt_one_ratio:
ratio_img = self.crop_l_r(img, self._lt_one_ratio, h, w)
else:
ratio_img = self.crop_d(img, self._lt_one_ratio, h, w)
resize_img = cv2.resize(ratio_img, (self._lt_one_inch_w, self._lt_one_inch_h))
elif size==1:
# 一寸
if img_ratio >= self._one_ratio:
ratio_img = self.crop_l_r(img, self._one_ratio, h, w)
else:
ratio_img = self.crop_d(img, self._one_ratio, h, w)
resize_img = cv2.resize(ratio_img, (self._one_inch_w, self._one_inch_h))
elif size==2:
# 小二寸
if img_ratio >= self._lt_two_ratio:
ratio_img = self.crop_l_r(img, self._lt_two_ratio, h, w)
else:
ratio_img = self.crop_d(img, self._lt_two_ratio, h, w)
resize_img = cv2.resize(ratio_img, (self._lt_two_inch_w, self._lt_two_inch_h))
elif size==3:
# 二寸
if img_ratio >= self._two_ratio:
ratio_img = self.crop_l_r(img, self._two_ratio, h, w)
else:
ratio_img = self.crop_d(img, self._two_ratio, h, w)
resize_img = cv2.resize(ratio_img, (self._two_inch_w, self._two_inch_h))
elif size==4:
# 五寸
if img_ratio >= self._five_ratio:
ratio_img = self.crop_l_r(img, self._five_ratio, h, w)
else:
ratio_img = self.crop_d(img, self._five_ratio, h, w)
resize_img = cv2.resize(ratio_img, (self._five_inch_w, self._five_inch_h))
elif size==5:
# 六寸
if img_ratio >= self._six_ratio:
ratio_img = self.crop_l_r(img, self._six_ratio, h, w)
else:
ratio_img = self.crop_d(img, self._six_ratio, h, w)
resize_img = cv2.resize(ratio_img, (self._six_inch_w, self._six_inch_h))
elif size==6:
# 七寸
if img_ratio >= self._seven_ratio:
ratio_img = self.crop_l_r(img, self._seven_ratio, h, w)
else:
ratio_img = self.crop_d(img, self._seven_ratio, h, w)
resize_img = cv2.resize(ratio_img, (self._seven_inch_w, self._seven_inch_h))
elif size==7:
# ID
if img_ratio >= self._id_ratio:
ratio_img = self.crop_l_r(img, self._id_ratio, h, w)
else:
ratio_img = self.crop_d(img, self._id_ratio, h, w)
resize_img = cv2.resize(ratio_img, (self._id_inch_w, self._id_inch_h))
else:
# 默认小二寸
if img_ratio >= self._lt_two_ratio:
ratio_img = self.crop_l_r(img, self._lt_two_ratio, h, w)
else:
ratio_img = self.crop_d(img, self._lt_two_ratio, h, w)
resize_img = cv2.resize(ratio_img, (self._lt_two_inch_w, self._lt_two_inch_h))
return resize_img
def crop_l_r(self, img, ratio, h, w):
"""
左右裁剪
图片大小比例 > ratio
"""
crop_w = int(ratio * h)
# 将w左右裁剪成这个crop_w的大小
hide_w = (w - crop_w) // 2
return_img = img[:, hide_w:w - hide_w]
return return_img
def crop_d(self, img, ratio, h, w):
"""
图片下裁剪
图片的大小比例 < ratio
"""
crop_h = int(w / ratio)
hide_h = h - crop_h
return_img = img[:h - hide_h, :]
return return_img
class test():
def __init__(self, win, PHYSN_TYPE, POS_NAME):
self.win = win
self.PHYSN_TYPE = PHYSN_TYPE
self.POS_NAME = POS_NAME
def my_GUI(self):
tk.Label(self.win, text='生成图片尺寸:', bd=3, relief='groove', width=16, anchor='e').grid(row=2, column=2, padx=5)
number = tk.StringVar() # 是否选中
valus = ['小一寸', '一寸', '小二寸', '二寸', '五寸', '六寸', '七寸', 'id card'] # 选项值设置
self.PHYSN_TYPE = ttk.Combobox(self.win, width=16, height=4, textvariable=number, state='readonly') # 高度,下拉显示的条目数量
self.PHYSN_TYPE.grid(row=2, column=3, columnspan=3)
self.PHYSN_TYPE['values'] = valus
self.PHYSN_TYPE.current(2) # 设置下拉列表默认显示的值
self.PHYSN_TYPE.bind('<>', self.Chosen) # 绑定选项(输出选中内容)
# print(self.PHYSN_TYPE.current(), self.PHYSN_TYPE.get()) # 输出选项内容
def Chosen(self, event):
print('生成图片尺寸:', self.PHYSN_TYPE.current())
global photoSize
photoSize=self.PHYSN_TYPE.current();
class bgColorTest():
def __init__(self, win, PHYSN_TYPE, POS_NAME):
self.win = win
self.PHYSN_TYPE = PHYSN_TYPE
self.POS_NAME = POS_NAME
def my_GUI(self):
tk.Label(self.win, text='生成图片背景:', bd=3, relief='groove', width=16, anchor='e').grid(row=4, column=2, padx=5)
number = tk.StringVar() # 是否选中
valus = ['红', '白', '蓝', ] # 选项值设置
self.PHYSN_TYPE = ttk.Combobox(self.win, width=16, height=4, textvariable=number, state='readonly') # 高度,下拉显示的条目数量
self.PHYSN_TYPE.grid(row=4, column=3, columnspan=3)
self.PHYSN_TYPE['values'] = valus
self.PHYSN_TYPE.current(0) # 设置下拉列表默认显示的值
self.PHYSN_TYPE.bind('<>', self.Chosen) # 绑定选项(输出选中内容)
# print(self.PHYSN_TYPE.current(), self.PHYSN_TYPE.get()) # 输出选项内容
def Chosen(self, event):
print('生成图片背景:', self.PHYSN_TYPE.current())
global photoBgSize
photoBgSize=self.PHYSN_TYPE.current();
class bgColorDown():
def __init__(self, win, PHYSN_TYPE, POS_NAME):
self.win = win
self.PHYSN_TYPE = PHYSN_TYPE
self.POS_NAME = POS_NAME
def my_GUI(self):
tk.Label(self.win, text='当前图片背景:', bd=3, relief='groove', width=16, anchor='e').grid(row=8, column=2, padx=5)
number = tk.StringVar() # 是否选中
valus = ['红', '白', '蓝', '绿'] # 选项值设置
self.PHYSN_TYPE = ttk.Combobox(self.win, width=16, height=4, textvariable=number, state='readonly') # 高度,下拉显示的条目数量
self.PHYSN_TYPE.grid(row=8, column=3, columnspan=3)
self.PHYSN_TYPE['values'] = valus
self.PHYSN_TYPE.current(0) # 设置下拉列表默认显示的值
self.PHYSN_TYPE.bind('<>', self.Chosen) # 绑定选项(输出选中内容)
# print(self.PHYSN_TYPE.current(), self.PHYSN_TYPE.get()) # 输出选项内容
def Chosen(self, event):
print('当前图片背景:', self.PHYSN_TYPE.current())
global downPhotoBgSize
downPhotoBgSize=self.PHYSN_TYPE.current();
# 图片生成程序方法
def gen_main(filePah,size):
# 读取照片
img=cv2.imread(filePah)
# 图像缩放
# img = cv2.resize(img,None,fx=0.5,fy=0.5)
imagesize = ImageSize();
img=imagesize.photo_size(img,size);
rows,cols,channels = img.shape
print(rows,cols,channels)
# cv2.imshow('img',img)
# 图片转换为灰度图
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
# cv2.imshow('hsv',hsv)
# 图片的二值化处理
# lower_blue=np.array([90,70,70])
# upper_blue=np.array([110,255,255])
if downPhotoBgSize==2:
# 蓝色
lower_blue = np.array([110, 50, 50])
upper_blue = np.array([130, 255, 255])
mask = cv2.inRange(hsv, lower_blue, upper_blue)
# 设定绿色的阈值
# 在 HSV 中,绿色的范围是 60-120
if downPhotoBgSize == 3:
# 绿
lower_green = np.array([40, 50, 50])
upper_green = np.array([70, 255, 255])
mask = cv2.inRange(hsv, lower_green, upper_green)
# 颜色识别(红色),过滤红色区域
if downPhotoBgSize == 0:
lower_red1 = np.array([0, 43, 46]) # 红色阈值下界
higher_red1 = np.array([10, 255, 255]) # 红色阈值上界
mask_red1 = cv2.inRange(hsv, lower_red1, higher_red1)
lower_red2 = np.array([156, 43, 46]) # 红色阈值下界
higher_red2 = np.array([180, 255, 255]) # 红色阈值上界
mask_red2 = cv2.inRange(hsv, lower_red2, higher_red2)
mask = cv2.add(mask_red1, mask_red2) # 拼接过滤后的mask
if downPhotoBgSize == 1:
# 白色
lower_white=np.array([0, 0, 221])
upper_white=np.array([0, 30, 255])
mask = cv2.inRange(hsv, lower_white, upper_white)
#腐蚀膨胀
dilate = cv2.dilate(mask, np.ones((5, 5), np.uint8), iterations=2)
cv2.imshow('dilate',dilate)
erode=cv2.erode(dilate,np.ones((5, 5), np.uint8),iterations=1)
cv2.imshow('erode',erode)
#遍历替换
for i in range(rows):
for j in range(cols):
if erode[i,j]==255: # 像素点为255表示的是白色,我们就是要将白色处的像素点,替换为红色
if photoBgSize==0:
img[i,j]=(0,0,255) # 红色 此处替换颜色,为BGR通道,不是RGB通道
if photoBgSize==1:
img[i,j]=(255,255,255) # 白色 此处替换颜色,为BGR通道,不是RGB通道
if photoBgSize==2:
img[i,j]=(219,142,67) # 蓝色 此处替换颜色,为BGR通道,不是RGB通道
# cv2.imshow('res',img)
save_path = "./test2.png"
cv2.imwrite(save_path, img)
global todoDownFile
todoDownFile=img
image = Image.open(save_path) # 创建Label组件,通过Image=photo设置要展示的图片
image = image.resize((80, 80))
panel = Label(master=win)
panel.photo = ImageTk.PhotoImage(image)
ll.config(image=panel.photo)
ll.image = panel.photo
def downFile():
times = datetime.now().strftime('%Y%m%d%H%M%S')
# 文件保存路径
wordFile = filedialog.asksaveasfilename(title='选择存放的位置!', initialdir=r'D:/',initialfile=times+".png",defaultextension=".png")
print(wordFile)
cv2.imwrite(wordFile, todoDownFile)
# 创建一个自定义函数,用于点击上传按钮的时候调用
def upload_pic():
# 这行代码会打开C:盘根目录,当你选中文件的时候,将文件的路径保存到pic_path变量
pic_path = filedialog.askopenfilename(initialdir='D:/')
global toPhotoImgpath
toPhotoImgpath = pic_path;
# 根据获取到的图片路径打开图片
img = Image.open(pic_path)
# 将图片固定设置为宽度为80,高度为80方便在界面中展示
img = img.resize((80, 80))
# 想修改完宽和高的图片保存
img.save('head.png')
# 加载保存的图片
head = PhotoImage(file='head.png')
# 将上传按钮中的图片设置为刚才加载的图片
head_button.config(image=head)
head_button.image=head
def gen_Start():
#
gen_main(toPhotoImgpath, photoSize)
if __name__ == "__main__":
# 创建窗口
win = tk.Tk()
# 设置窗口标题
win.title('图片调整尺寸及背景')
# 设置窗口宽度和高度
win.geometry('270x350')
# 图片尺寸选择
test(win,None,None).my_GUI()
# 生成图片背景
bgColorTest(win,None,None).my_GUI()
# # 加载一个默认图片,用于在上传按钮中显示
tk.Label(win, text='选择图片:', bd=3, relief='groove', width=16, anchor='e').grid(row=6, column=2, padx=5,pady=50)
# 创建一个按钮,设置按钮中要显示的图片,以及点击按钮是调用的函数
head_button =tk. Button( command=upload_pic)
# 将按钮放置在x坐标为150,y坐标为10的位置,并且设置宽度和高度都是80
head_button.place(x=150, y=60, width=80, height=80)
# 当前图片背景
bgColorDown(win, None, None).my_GUI()
tmp = open('22.png', 'wb') # 创建临时的文件
tmp.write(base64.b64decode(
"iVBORw0KGgoAAAANSUhEUgAAAHgAAAB9CAYAAABpqadhAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAKWSURBVHhe7djrcYQgAABh+7Ee+rEe67l+iCh6YNDkfmQiO7sz5GHUZPxAczdEQycwPIHhCQxPYHgCwxMYnsDwBIYnMDyB4QkMT2B4AsMTGJ7A8ASGJzA8geEJDE9geALDExiewPAEhicwPIHhCQxPYHgCwxMYnsDwBIYnMDyB4QkMT2B4AsMTGJ7A8ASGJzA8geEJDE9geALDExiewPAEhicwPIHhCQxPYHgCwxMYnsDwBIYnMDyB4XUCPMcwTvGVv6uaQxzCnL8pW44ZwvLx3RyGuO76muJ4db7iuNc0xmEYLkZ97qfWzwreIdPn5gV/j3HKdGnfA7IA/yVwKiEf58ut8M1J9by6ukXPYYyna70h3lzsfdXer8btvGnfcvsOu27PE2L9uhPcVIfP4FecxhqiHo1JsK7KYvsHK3ir+J0d4aY6AC4ubgvlYgUfq7F1zMfP4GJylI+IDrD7WcEZZTrdRptjx8vHzLe35zwOrAS8bav9Wiv7+XUHvMJdPXfP27+t1ALp2znKW3/eJx2/T4DGaP0JT6tf4MYFX8cd8NUkqbCvVqor+G+7wik7b6+At1tv9RIq71u/FBL4f8pY6XkawoJzXrn7KIETYgJOxy4/q+ZE3rYdV/7nvUP+9N/6Mo7J89z6Ak4XNSn9ZgWnrxeo8PHrVlfwv1TdRk/A5RsU7zcn3qvy/k2OPJbzHfs1J4TA9sAEhicwPIHhCQxPYHgCwxMYnsDwBIYnMDyB4QkMT2B4AsMTGJ7A8ASGJzA8geEJDE9geALDExiewPAEhicwPIHhCQxPYHgCwxMYnsDwBIYnMDyB4QkMT2B4AsMTGJ7A8ASGJzA8geEJDE9geALDExiewPAEhicwPIHhCQxPYHQxfgEoWUyJedbwDwAAAABJRU5ErkJggg==")) ##把这个one图片解码出来,写入文件中去。
tmp.close()
tmp = open('33.png', 'wb') # 创建临时的文件
tmp.write(base64.b64decode(
"iVBORw0KGgoAAAANSUhEUgAAAT0AAADTCAYAAADzosTbAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAKqSURBVHhe7dQBAQAACMMg+5e+QQYhuAGESA9IkR6QIj0gRXpAivSAFOkBKdIDUqQHpEgPSJEekCI9IEV6QIr0gBTpASnSA1KkB6RID0iRHpAiPSBFekCK9IAU6QEp0gNSpAekSA9IkR6QIj0gRXpAivSAFOkBKdIDUqQHpEgPSJEekCI9IEV6QIr0gBTpASnSA1KkB6RID0iRHpAiPSBFekCK9IAU6QEp0gNSpAekSA9IkR6QIj0gRXpAivSAFOkBKdIDUqQHpEgPSJEekCI9IEV6QIr0gBTpASnSA1KkB6RID0iRHpAiPSBFekCK9IAU6QEp0gNSpAekSA9IkR6QIj0gRXpAivSAFOkBKdIDUqQHpEgPSJEekCI9IEV6QIr0gBTpASnSA1KkB6RID0iRHpAiPSBFekCK9IAU6QEp0gNSpAekSA9IkR6QIj0gRXpAivSAFOkBKdIDUqQHpEgPSJEekCI9IEV6QIr0gBTpASnSA1KkB6RID0iRHpAiPSBFekCK9IAU6QEp0gNSpAekSA9IkR6QIj0gRXpAivSAFOkBKdIDUqQHpEgPSJEekCI9IEV6QIr0gBTpASnSA1KkB6RID0iRHpAiPSBFekCK9IAU6QEp0gNSpAekSA9IkR6QIj0gRXpAivSAFOkBKdIDUqQHpEgPSJEekCI9IEV6QIr0gBTpASnSA1KkB6RID0iRHpAiPSBFekCK9IAU6QEp0gNSpAekSA9IkR6QIj0gRXpAivSAFOkBKdIDUqQHpEgPSJEekCI9IEV6QIr0gBTpASnSA1KkB6RID0iRHpAiPSBFekCK9IAU6QEp0gNSpAekSA9IkR6QIj0gRXpAivSAFOkBKdIDUqQHpEgPSJEekCI9IEV6QIr0gBTpASnSA1KkB6RID0iRHhCyPTbTQ+SCtTgPAAAAAElFTkSuQmCC")) ##把这个one图片解码出来,写入文件中去。
tmp.close()
head = PhotoImage(file='22.png')
# 将上传按钮中的图片设置为刚才加载的图片
head_button.config(image=head)
head_button.image = head
tk.Label(win, text='生成的图片:', bd=3, relief='groove', width=16, anchor='e').grid(row=10, column=2, padx=5, pady=50)
image = Image.open('33.png') # 创建Label组件,通过Image=photo设置要展示的图片
image=image.resize((80, 80))
panel = Label(master=win)
panel.photo = ImageTk.PhotoImage(image) # 将原本的变量photo改为panel.photo
global ll
ll=Label(master=win, image=panel.photo, bd=3, relief='groove', width=80)
ll.grid(row=10, column=4, padx=5, pady=10)
# 生成
gen_button = tk.Button(text='生成',command=gen_Start)
# 将按钮放置在x坐标为150,y坐标为10的位置,并且设置宽度和高度都是80
gen_button.place(x=50, y=310, width=80, height=20)
# 下载
downFileButton = tk.Button(text='下载',command=downFile)
# 将按钮放置在x坐标为150,y坐标为10的位置,并且设置宽度和高度都是80
downFileButton.place(x=150, y=310, width=80, height=20)
# 主循环
win.mainloop()