python 证件更换背景及调整大小

仅供参考,未完善,老铁轻喷

程序包:

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('<<ComboboxSelected>>', 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('<<ComboboxSelected>>', 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('<<ComboboxSelected>>', 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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值