证件照一键换底色小工具

  • 2019-10-19
  • 188
  • 4
  • 1

最新源码

import os
import time
import base64
import threading
import requests
from lxml import etree
from icon import img1
from tkinter import *
from tkinter import ttk, messagebox, scrolledtext
from tkinter.filedialog import askopenfilename
from PIL import Image
from removebg import RemoveBg


def status():
    global key
    # 创建存放API_KEY文件
    if os.path.exists('./key.txt') == False:
        with open('./key.txt', 'a') as fc:
            fc.write("")
    with open('./key.txt', 'r', encoding='utf-8') as f:
        txt = f.read()
    key = txt.split("\n")
    # 判断是否能正常访问服务器数据
    try:
        requests.get("http://shuaiguoer.com/bg/")
    except requests.exceptions.ConnectionError:
        photo_offline()
    else:
        photo()


def photo():
    # 版本检测更新
    def version():
        version_number = 3.0       # 当前软件版本

        # 下载最新版本
        def download():
            # 获取文件大小                        headers内没有 content-length 的情况下
            var.set("正在启动下载,请稍后...")
            response_size = requests.get("http://pan.shuaiguoer.com/software/bg")
            html_size = etree.HTML(response_size.content.decode())
            version_name_size = html_size.xpath('//div[@class="mdui-col-sm-2 mdui-text-right"]/text()')
            length = float(version_name_size[-1].split("MB")[0]) * 1024 * 1024
            # 获取下载进度
            url = "http://pan.shuaiguoer.com/software/bg/%E8%AF%81%E4%BB%B6%E7%85%A7%E6%8D%A2%E5%BA%95%20" \
                  + str(now_number) + ".exe"
            headers = {'Proxy-Connection': 'keep-alive'}
            r = requests.get(url, stream=True, headers=headers)
            # length = float(r.headers['content-length'])           # 适用于headers内带有 content-length 的情况下
            user_name = os.environ['USERNAME']
            with open(r"C:/Users/" + user_name + "/Desktop/" + version_name[-1], 'wb') as fd:
                count = 0
                count_tmp = 0
                time1 = time.time()
                for chunk in r.iter_content(chunk_size=512):
                    if chunk:
                        fd.write(chunk)
                        count += len(chunk)
                        if time.time() - time1 > 2:
                            p = count / length
                            speed = (count - count_tmp) / 1024 / 2
                            count_tmp = count
                            time1 = time.time()
                            var.set("下载进度:{:.2%}    下载速度:{:.2f}KB/s".format(p, speed))
            update.destroy()
            messagebox.showinfo(title="Successful", message="更新完成,请重新打开新版本!")
        # 检测当前是否为最新版本
        response = requests.get("http://pan.shuaiguoer.com/software/bg/")
        html = etree.HTML(response.content.decode())
        version_name = html.xpath('//div[@class="mdui-col-xs-12 mdui-col-sm-7 mdui-text-truncate"]/span/text()')
        now_number = version_name[-1].split(" ")[1].split(".exe")[0]
        # 公告检测
        up_window = ""
        response = requests.get("http://shuaiguoer.com/bg/")
        html = etree.HTML(response.content.decode())
        version_info = html.xpath('//*[@id="article"]/p/text()')
        try:
            up_window = str(version_info[0]).split(":")[1]
        except IndexError:
            messagebox.showinfo(title="error", message="服务器状态异常")
        # 弹窗提示
        if not up_window == "":
            messagebox.showinfo(title="tips", message=up_window)
        # 版本检测
        if version_number < float(now_number):
            Tk().withdraw()
            if messagebox.askokcancel(title="更新!", message="检测到新版本!\n是否查看更新?"):
                update = Toplevel(root)
                update.title("下载更新")
                update.geometry('390x239+168+250')
                update.wm_attributes("-alpha", 0.9)  # 设置透明度
                update.wm_attributes("-toolwindow", True)  # 置为工具窗口(没有最大最小按钮)
                # 标签
                label = Label(update, text="更新公告", font=('GB2312', 16), fg='red')
                label.grid(row=0, column=0, pady=10)
                # 滚动文本
                scr = scrolledtext.ScrolledText(update, width=50, height=10)
                scr.grid(row=1, column=0, padx=10)
                # 公告更新
                for i in version_info[1:]:
                    scr.insert('end', i + "\n\n")
                    scr.see(END)      # 设置消息框,默认显示最新内容
                # 标签
                var = StringVar()
                label_up = Label(update, textvariable=var, font=("楷体", 10))
                label_up.grid(row=2, column=0, padx=10, pady=10, sticky=W)
                # 按钮
                button_down = Button(update, text="下载最新版本", command=lambda: thread_it(download))
                button_down.grid(row=2, column=0, padx=10, pady=10, sticky=E)

    # 多线程
    def thread_it(func, *args):
        """将函数打包进线程"""
        # 创建
        t = threading.Thread(target=func, args=args)
        # 守护 !!!
        t.setDaemon(True)
        # 启动
        t.start()

    # 获取路径
    def select_path():
        global find_path
        find_path = askopenfilename()
        path.set(find_path)

    # 设为默认KEY
    def default():
        i = key.index(combobox.get())
        j = key.index(key[0])
        key[i], key[j] = key[j], key[i]
        dd = "\n".join(key)
        with open('./key.txt', 'w') as ff:
            ff.write(dd)
        messagebox.showinfo(title="info", message="已成功设置为默认API_KEY")

    # 生成
    def replacement():
        try:
            nobg = find_path + "_no_bg.png"
        except NameError:
            messagebox.showwarning(title="warning", message="请选择照片")
        else:
            button3.grid_forget()
            var.set("正在生成照片中,请稍等...")
            if nobg.split("/")[-1] in os.listdir('/'.join(find_path.split("/")[:-1])):
                pass
            else:
                rmbg = RemoveBg(combobox.get(), 'error.log')
                rmbg.remove_background_from_img_file(find_path)
            try:
                Image.open(nobg)
            except FileNotFoundError:
                messagebox.showwarning(title="warning", message="您的API_KEY本月额度已用完,或者API_KEY无效\n\n请在更换API_KEY后重试!")
                var.set("")
                button3.grid(row=3, column=0, columnspan=3, pady=20)
            else:
                try:
                    if var1.get() == var2.get() == var3.get() == 1:
                        im = Image.open(nobg)
                        x, y = im.size
                        br1 = Image.new('RGBA', im.size, (67, 142, 219))
                        br2 = Image.new('RGBA', im.size, (255, 0, 0))
                        br3 = Image.new('RGBA', im.size, (255, 255, 255))
                        br1.paste(im, (0, 0, x, y), im)
                        br2.paste(im, (0, 0, x, y), im)
                        br3.paste(im, (0, 0, x, y), im)
                        br1.save(find_path + '_blue_bg.png')
                        br2.save(find_path + '_red_bg.png')
                        br3.save(find_path + '_white_bg.png')
                    elif var1.get() == 1 != var2.get() and var3.get() == 0:
                        im = Image.open(nobg)
                        x, y = im.size
                        b = Image.new('RGBA', im.size, (67, 142, 219))
                        b.paste(im, (0, 0, x, y), im)
                        b.save(find_path + '_blue_bg.png')
                        button2.grid()
                    elif var2.get() == 1 != var3.get() and var1.get() == 0:
                        im = Image.open(nobg)
                        x, y = im.size
                        r = Image.new('RGBA', im.size, (255, 0, 0))
                        r.paste(im, (0, 0, x, y), im)
                        r.save(find_path + '_red_bg.png')
                    elif var3.get() == 1 != var1.get() and var2.get() == 0:
                        im = Image.open(nobg)
                        x, y = im.size
                        w = Image.new('RGBA', im.size, (255, 255, 255))
                        w.paste(im, (0, 0, x, y), im)
                        w.save(find_path + '_white_bg.png')
                    elif var1.get() == var2.get() == 1 and var3.get() == 0:
                        im = Image.open(nobg)
                        x, y = im.size
                        br1 = Image.new('RGBA', im.size, (67, 142, 219))
                        br2 = Image.new('RGBA', im.size, (255, 0, 0))
                        br1.paste(im, (0, 0, x, y), im)
                        br2.paste(im, (0, 0, x, y), im)
                        br1.save(find_path + '_blue_bg.png')
                        br2.save(find_path + '_red_bg.png')
                    elif var1.get() == var3.get() == 1 and var2.get() == 0:
                        im = Image.open(nobg)
                        x, y = im.size
                        bw1 = Image.new('RGBA', im.size, (67, 142, 219))
                        bw2 = Image.new('RGBA', im.size, (255, 255, 255))
                        bw1.paste(im, (0, 0, x, y), im)
                        bw2.paste(im, (0, 0, x, y), im)
                        bw1.save(find_path + '_blue_bg.png')
                        bw2.save(find_path + '_white_bg.png')
                    elif var2.get() == var3.get() == 1 and var1.get() == 0:
                        im = Image.open(nobg)
                        x, y = im.size
                        rw1 = Image.new('RGBA', im.size, (255, 0, 0))
                        rw2 = Image.new('RGBA', im.size, (255, 255, 255))
                        rw1.paste(im, (0, 0, x, y), im)
                        rw2.paste(im, (0, 0, x, y), im)
                        rw1.save(find_path + '_red_bg.png')
                        rw2.save(find_path + '_white_bg.png')
                    else:
                        messagebox.showwarning(title="warning", message="请选择要生成的底色!")
                    var.set("")
                    button3.grid(row=3, column=0, columnspan=3, pady=20)
                except BaseException:
                    with open('./error.log', 'a') as f:
                        f.write('background change fail .')
                    messagebox.showerror(title="error", message="背景更改失败")

    # 写入图片数据
    with open("img1.ico", 'wb+') as f:
        f.write(base64.b64decode(img1))

    root = Tk()
    root.title("证件照换底色 3.0")
    root.geometry('550x260+560+250')
    root.iconbitmap("img1.ico")
    os.remove("img1.ico")
    root.wm_attributes("-alpha", 0.9)
    path = StringVar()
    var = StringVar()
    # 选择框变量
    var1 = IntVar()     # 蓝底
    var2 = IntVar()     # 红底
    var3 = IntVar()     # 白底
    # 标签
    label1 = Label(root, text="API_KEY:", font=('GB2312', 16))
    label1.grid(row=0, column=0, padx=10, pady=15)
    label2 = Label(root, text="照片路径:", font=('GB2312', 16))
    label2.grid(row=1, column=0, padx=10, pady=15)
    label3 = Label(root, textvariable=var, font=('GB2312', 16))
    label3.grid(row=3, column=0, columnspan=3, pady=15)
    # 下拉选择框
    combobox = ttk.Combobox(root, width=39, font=('GB2312', 12))
    combobox.grid(row=0, column=1)
    combobox['value'] = key
    combobox.current(0)
    # 文本框
    entry1 = Entry(root, width=30, font=('GB2312', 16), textvariable=path)
    entry1.grid(row=1, column=1)
    # 勾选框
    checkbutton1 = Checkbutton(root, text="蓝底", fg='blue', font=('GB2312', 16), variable=var1, onvalue=1, offvalue=0)
    checkbutton1.grid(row=2, column=0, pady=20)
    checkbutton2 = Checkbutton(root, text="红底", fg='red', font=('GB2312', 16), variable=var2, onvalue=1, offvalue=0)
    checkbutton2.grid(row=2, column=1)
    checkbutton3 = Checkbutton(root, text="白底", font=('GB2312', 16), variable=var3, onvalue=1, offvalue=0)
    checkbutton3.grid(row=2, column=2)
    # 按钮
    button1 = Button(root, text="设为默认", command=lambda: thread_it(default))
    button1.grid(row=0, column=2, padx=10)
    button2 = Button(root, text="选择路径", command=lambda: thread_it(select_path))
    button2.grid(row=1, column=2, padx=10)
    button3 = Button(root, text="一  键  换  底  色", font=('GB2312', 16), command=lambda: thread_it(replacement))
    button3.grid(row=3, column=0, columnspan=3, pady=15)
    version()
    root.mainloop()


def photo_offline():
    # 获取路径
    def select_path():
        global find_path
        find_path = askopenfilename()
        path.set(find_path)

    # 设为默认KEY
    def default():
        i = key.index(combobox.get())
        j = key.index(key[0])
        key[i], key[j] = key[j], key[i]
        dd = "\n".join(key)
        with open('./key.txt', 'w') as ff:
            ff.write(dd)
        messagebox.showinfo(title="info", message="已成功设置为默认API_KEY")

    # 生成
    def replacement():
        try:
            nobg = find_path + "_no_bg.png"
        except NameError:
            messagebox.showwarning(title="warning", message="请选择照片")
        else:
            button3.grid_forget()
            var.set("正在生成照片中,请稍等...")
            if nobg.split("/")[-1] in os.listdir('/'.join(find_path.split("/")[:-1])):
                pass
            else:
                # rmbg = RemoveBg('yp86HAMuLhdVqVu82Ajmj22A', 'error.log')
                rmbg = RemoveBg(combobox.get(), 'error.log')
                rmbg.remove_background_from_img_file(find_path)
            try:
                Image.open(nobg)
            except FileNotFoundError:
                messagebox.showwarning(title="warning", message="您的API_KEY本月额度已用完,或者API_KEY无效\n\n请在更换API_KEY后重试!")
                var.set("")
                button3.grid(row=3, column=0, columnspan=3, pady=20)
            else:
                try:
                    if var1.get() == var2.get() == var3.get() == 1:
                        im = Image.open(nobg)
                        x, y = im.size
                        br1 = Image.new('RGBA', im.size, (67, 142, 219))
                        br2 = Image.new('RGBA', im.size, (255, 0, 0))
                        br3 = Image.new('RGBA', im.size, (255, 255, 255))
                        br1.paste(im, (0, 0, x, y), im)
                        br2.paste(im, (0, 0, x, y), im)
                        br3.paste(im, (0, 0, x, y), im)
                        br1.save(find_path + '_blue_bg.png')
                        br2.save(find_path + '_red_bg.png')
                        br3.save(find_path + '_white_bg.png')
                    elif var1.get() == 1 != var2.get() and var3.get() == 0:
                        im = Image.open(nobg)
                        x, y = im.size
                        b = Image.new('RGBA', im.size, (67, 142, 219))
                        b.paste(im, (0, 0, x, y), im)
                        b.save(find_path + '_blue_bg.png')
                        button2.grid()
                    elif var2.get() == 1 != var3.get() and var1.get() == 0:
                        im = Image.open(nobg)
                        x, y = im.size
                        r = Image.new('RGBA', im.size, (255, 0, 0))
                        r.paste(im, (0, 0, x, y), im)
                        r.save(find_path + '_red_bg.png')
                    elif var3.get() == 1 != var1.get() and var2.get() == 0:
                        im = Image.open(nobg)
                        x, y = im.size
                        w = Image.new('RGBA', im.size, (255, 255, 255))
                        w.paste(im, (0, 0, x, y), im)
                        w.save(find_path + '_white_bg.png')
                    elif var1.get() == var2.get() == 1 and var3.get() == 0:
                        im = Image.open(nobg)
                        x, y = im.size
                        br1 = Image.new('RGBA', im.size, (67, 142, 219))
                        br2 = Image.new('RGBA', im.size, (255, 0, 0))
                        br1.paste(im, (0, 0, x, y), im)
                        br2.paste(im, (0, 0, x, y), im)
                        br1.save(find_path + '_blue_bg.png')
                        br2.save(find_path + '_red_bg.png')
                    elif var1.get() == var3.get() == 1 and var2.get() == 0:
                        im = Image.open(nobg)
                        x, y = im.size
                        bw1 = Image.new('RGBA', im.size, (67, 142, 219))
                        bw2 = Image.new('RGBA', im.size, (255, 255, 255))
                        bw1.paste(im, (0, 0, x, y), im)
                        bw2.paste(im, (0, 0, x, y), im)
                        bw1.save(find_path + '_blue_bg.png')
                        bw2.save(find_path + '_white_bg.png')
                    elif var2.get() == var3.get() == 1 and var1.get() == 0:
                        im = Image.open(nobg)
                        x, y = im.size
                        rw1 = Image.new('RGBA', im.size, (255, 0, 0))
                        rw2 = Image.new('RGBA', im.size, (255, 255, 255))
                        rw1.paste(im, (0, 0, x, y), im)
                        rw2.paste(im, (0, 0, x, y), im)
                        rw1.save(find_path + '_red_bg.png')
                        rw2.save(find_path + '_white_bg.png')
                    else:
                        messagebox.showwarning(title="warning", message="请选择要生成的底色!")
                    var.set("")
                    button3.grid(row=3, column=0, columnspan=3, pady=20)
                except BaseException:
                    with open('./error.log', 'a') as f:
                        f.write('background change fail .')
                    messagebox.showerror(title="error", message="背景更改失败")

    # 写入图片数据
    with open("img1.ico", 'wb+') as f:
        f.write(base64.b64decode(img1))
    # 软件界面
    root = Tk()
    root.title("证件照换底色 3.0")
    root.geometry('550x255+560+250')
    root.iconbitmap("img1.ico")
    os.remove("img1.ico")
    root.wm_attributes("-alpha", 0.9)
    path = StringVar()
    var = StringVar()
    # 选择框变量
    var1 = IntVar()  # 蓝底
    var2 = IntVar()  # 红底
    var3 = IntVar()  # 白底
    # 标签
    label1 = Label(root, text="API_KEY:", font=('GB2312', 16))
    label1.grid(row=0, column=0, padx=10, pady=15)
    label2 = Label(root, text="照片路径:", font=('GB2312', 16))
    label2.grid(row=1, column=0, padx=10, pady=15)
    label3 = Label(root, textvariable=var, font=('GB2312', 16))
    label3.grid(row=3, column=0, columnspan=3, pady=15)
    label4 = Label(root, text="离线状态", font=('GB2312', 10), fg="red")
    label4.grid(row=3, column=0, padx=10, pady=10, sticky=SW)
    # 下拉选择框
    combobox = ttk.Combobox(root, width=39, font=('GB2312', 12))
    combobox.grid(row=0, column=1)
    combobox['value'] = key
    combobox.current(0)
    # 文本框
    entry1 = Entry(root, width=30, font=('GB2312', 16), textvariable=path)
    entry1.grid(row=1, column=1)
    # 勾选框
    checkbutton1 = Checkbutton(root, text="蓝底", fg='blue', font=('GB2312', 16), variable=var1, onvalue=1, offvalue=0)
    checkbutton1.grid(row=2, column=0, pady=20)
    checkbutton2 = Checkbutton(root, text="红底", fg='red', font=('GB2312', 16), variable=var2, onvalue=1, offvalue=0)
    checkbutton2.grid(row=2, column=1)
    checkbutton3 = Checkbutton(root, text="白底", font=('GB2312', 16), variable=var3, onvalue=1, offvalue=0)
    checkbutton3.grid(row=2, column=2)
    # 按钮
    button1 = Button(root, text="设为默认", command=default)
    button1.grid(row=0, column=2, padx=10)
    button2 = Button(root, text="选择路径", command=select_path)
    button2.grid(row=1, column=2, padx=10)
    button3 = Button(root, text="一  键  换  底  色", font=('GB2312', 16), command=replacement)
    button3.grid(row=3, column=0, columnspan=3, pady=15)
    root.mainloop()


status()

更新记录

1.0:完善基本功能

2.0:优化用户体验,修复路径BUG

 

3.0:修复由于服务器故障,导致软件强制退出的BUG,并增加检测服务器当前状态等功能。
提高API_KEY次数重复使用率。  增加API_KEY次数使用完以后的提示。
增加API_KEY选择功能,并可手动设定为默认KEY。
修复数个目前已知的小BUG,优化用户体验。

 

评论

      • 小邓子回复
        Google Chrome 63 Google Chrome 63 Windows 7 Windows 7

        怎么回事啊小老弟

        • shuai
          shuai回复
          QQbrowser QQbrowser Android 9 Android 9

          小老弟,你飘了 :yinxian:

发表评论

:zhenbang: :yiwen: :yinyue: :yinxian: :yi: :xxyl: :xinsui: :xiaonian: :weiqu: :tushe: :tu: :taiyang: :taikaixin: :shuijiao: :shenli: :shengqi: :ruo: :qianbi: :qian: :pen: :neng: :mianqiang: :meigui: :lu: :liwu: :kuanghan: :ku: :kaixin: :jinya: :jiku: :huaxin: :huaji: :hu: :heixian: :hehe: :han: :haha: :haha2: :guai: :dangao: :damuzhi: :daku: :chabei: :caihong: :bugaoxing: :bishi: :aixin: :a: :OK: :) :(