最近刚学了python(学习了3个月整),正在做个软件项目。突然有一天,一位朋友发来威信吐槽道:唉,刚换了工作,又得换工作照,去拍照太麻烦,去PS也得花个个把小时还不一定修的好,去美图秀秀吧,竟然换一张照片的背景底色还要收我5.9元钱。于是老铁就问我有没有办法解决一下他的这个问题。
那当然,python在手,吃遍所有!当即我就满足了他的需求。大致情况如下,感兴趣的小伙伴可以嫖一嫖:
我是在python3.7版本,win10,64位系统下编写的。只要你自己的系统和版本满足你平常的项目需求,都没有问题,你的也可以直接运行,没必要非要和我的一样。
项目开始之前,我们需要先去一个地方:
removebg官网
,这个网站是可以去除照片背景的,让我们的照片变成png格式的透明底色照片,所以我们先去注册一个账号:
我是用自己的邮箱注册的,然后它们官网会发送一个验证链接到你的邮箱里,直接点击验证就好了。之后你就可以直接进入官网了,然后在官网中找到my dashbord进入,网页自动翻译我记得好像是我的仪表盘吧,如下图:
进入之后你会看到API Keys,再点击New API Key,我们就可以直接获取一个自己账号专属的API Key号码,一定要复制粘贴保存好保存好保存好(重要的事情说3遍)这个API Key号码,这次的项目我们需要用到。如下图:
另外需要提醒的就是removebg官网限制每个专属API每个月只能免费使用50次,也就是50张照片,你如果需求量特别大,需要花钱成为vip。一般我们自己或者帮别人换个工作照底色,一个月50次已经超够用了。
好了,前期工作我们已经做好了,下面就可以开始编辑我们的程序代码了!
这个小项目利用python和GUI实现照片/证件照迅速更换背景底色,还可以自定义背景底色!因此是基于GUI-tkinter图形交互界面实现的功能,所以我们需要先建立运行窗口。我是在vscode中编辑的py文件,所以首先我们要在新建的main.py文件中导入需要用的包,没有安装的包可以直接键盘win+R去运行cmd,执行安装命令,缺少哪个就安装哪个,安装命令:pip install xxx
from tkinter import *
from removebg import RemoveBg
from tkinter import filedialog
from PIL import Image
from tkinter import colorchooser
import os
然后我们需要新建一个运行窗口,不熟悉GUI-tkinter图形交互界面的小伙伴可以自行搜索,很简单很好学,我当时花了一个多星期(年纪大了记性不好,唉)把它其中常用的相关功能琢磨了个遍,就动手创作了。当然熟悉它的小伙伴我们直接上代码就好了。
#创建窗口
window=Tk()
window.withdraw()
#刷新窗口
window.update()
#窗口标题
window.title('证件照换底工具')
#窗口ico图标
window.iconbitmap('um.ico')#此处需要更换成你自己的ico图标
#窗口不允许更改大小,为了方便设置后续的功能
window.resizable(0,0)
#设置窗口大小
width=520
height=300
#实现窗口自动在电脑屏幕居中
screenwidth=window.winfo_screenwidth()
screenheight=window.winfo_screenheight()
login_size='%dx%d+%d+%d'%(width,height,(screenwidth-width)/2,
(screenheight-height)/2-20)
window.geometry(login_size)
#展示窗口
window.deiconify()
#运行窗口
window.mainloop()
以上代码我们实现了在电脑桌面上创建并运行功能窗口的小目标,点击运行后它会在你的电脑桌面上出现这样的图形:
看上去有些简单了,我们就接着去实现我们的第一个功能:让用户自定义照片的底色。我们创建了第一个函数col(),是为了在后面我们创建的《自定义底色》按钮使用的,因为我们这个按钮需要调用它这个函数内的功能,对于一些刚接触python的小伙伴,说是说不清楚的,我们接着上代码,看看效果就晓得了:
def col():
global colorvalue
root = Toplevel(window)
root.withdraw()
root.update()
root.title('照片底色')
root.iconbitmap('um.ico')
root.resizable(0,0)
width=520
height=300
screenwidth=window.winfo_screenwidth()
screenheight=window.winfo_screenheight()
login_size='%dx%d+%d+%d'%(width,height,(screenwidth-width)/2,
(screenheight-height)/2-20)
window.geometry(login_size)
window.deiconify()
#创建一个自定义选择颜色的面板
colorvalue = colorchooser.askcolor()
#让我们选择的颜色出现在创建的窗口中
label2=Label(font=('Times', 12, 'bold'))
label2['text']=colorvalue
label2.place(x=160,y=65)
#这里我们让这个颜色值在运行窗口中只显示3秒种就隐藏消失
label2.after(3000,label2.destroy)
运行效果如下:怎么样?这样我们就可以想定义什么底色就定义什么底色了!而不再局限于工作照的红蓝白底了!
接下来,我们就要实现我们的第二个小功能了,那就是我们的照片在电脑上保存着,我们怎么获取到它的路径和照片的名字呢?也很简单,我们接着再定义一个函数就好,上代码:
def open_img():
global img
global filepath
try:
filepath = filedialog.askopenfilename() # 打开文件,返回该文件的完整路径
filename.set(filepath)
img = Image.open(filename.get())
#如果报错就执行:
except Exception as e:
print("没有选择任何文件",e)
在上面的代码中,我们用filsdialog的askopenfilename()方法实现了打开电脑文件和获取文件名字(也就是你需要修改的照片的路径和名字)的功能,这样就完了吗?对啊,这样就完了!是不是超级简单!接下来我们就可以去实现我们的核心功能——照片换底功能了!
def chack():
global new_image
#获取上面函数中我们定义好的照片路径和名称
old_image_path=filepath
#输入我们在removebg官网注册后获取的API Key
api_key="你自己注册获取的API Key"#这里你自己替换吧!
rmbg = RemoveBg(api_key, "error.log")
rmbg.remove_background_from_img_file(old_image_path)
color=colorvalue[0]
parent_path = os.path.dirname(old_image_path)
old_image_name = os.path.split(old_image_path)[-1]
no_bg_image_name = old_image_name + "_no_bg.png"
if no_bg_image_name in os.listdir(parent_path):
no_bg_image_path = parent_path + "/" + no_bg_image_name
no_bg_image = Image.open(no_bg_image_path)
x, y = no_bg_image.size
try:
new_image = Image.new('RGBA', no_bg_image.size, color=color)
new_image.paste(no_bg_image, (0, 0, x, y), no_bg_image)
#如果换底色成功,就在窗口上显示:转换完成,请保存!
label=Label(font=('Times', 12, 'bold'))
label['text']='转换完成,请保存!'
label.place(x=160,y=165)
label.after(3000,label.destroy)
except:
print("except")
else:
print("fail")
这里的代码稍微有些长,但是很好理解,其中api_key变量赋值就是我们最开始注册removebg官网后获取保存的那一大串API Key,直接把那一段“xxxxxx”替换掉就好了。然后下面那一大段代码其实就是实现我们照片去除背景色——重命名的过程。再后面的try中的代码,其中color=color,这个color就是我们前面已经自定义选择好的颜色值。到这里,我们的核心功能也实现了。结束了吗?当然还没有,我们得把转换好的照片保存在自己的电脑中吧!那好,接着来:
def save_png():
try:
filetypes = [("PNG","*.png")]
filenewpath= filedialog.asksaveasfilename(title='保存文件',filetypes=filetypes,
defaultextension='.png',initialdir='C:/Users/Administrator/Desktop' )
path_var.set(filenewpath)
new_image.save(filenewpath)
except Exception as e:
print(e)
上面代码中,filedialog.asksaveasfilename()方法的使用,就是我们可以实现的功能:将换好底色的照片以png格式保存在我们电脑上想要保存的地方,new_image.save(filenewpath)就是执行了我们最后一步保存的功能。注意:必须是png格式,不要问我为什么!
好了,到了这里我们需要实现的功能全部完成,接下来也就进入到了我们最后的阶段,完善我们的运行窗口,还记得文章开头那个灰不溜秋的运行窗口吗?就是它,我们需要在它上面放置一些需要用到的按钮和文本框,以此实现上面写好的功能的调用,相关的注释我已经写在了代码中,小伙伴们可以参考:
#首先,就是设置自定义背景色的功能按钮
filename = StringVar()
path_var = StringVar()
text=Label(window,text="请选择背景色",font=('Times', 14, 'bold'))
#设置文本位置
text.place(x=200,y=20)
#设置按钮位置
Button(window, text="自定义底色", command=col).place(x=320,y=60)
# 然后,设置选择照片和实现底色转换的功能按钮和显示位置
entry = Entry(window, textvariable=filename)
entry.place(x=150,y=115,width=160, height=25)
Button(window, text='选择文件', command=open_img).place(x=332,y=110)
Button(window, text='点击转换', command=chack).place(x=332,y=160)
# 最后,设置保存换底色成功后的照片的功能按钮和显示位置
entry1 = Entry(window, textvariable=path_var)
entry1.place(x=150,y=215,width=160, height=25)
Button(window, text='保存文件', command=save_png).place(x=332,y=210)
最后的最后,我们将最上面刚开始创建运行窗口时的最后一句代码:window.mainloop(),这句代码改到我们本项目所有代码最后一行就好了,其实刚开始那里放置这句代码纯属是为了向大家展示那个运行窗口的效果图而已,到这里我们的所有功能和按钮都设置好了,我们就把它放在所有代码的最下面一行就好了,因为它表示我们可以开始运行窗口了,下面是运行效果图:
我们看一下它的实现效果吧:
怎么样?效果还是很拽的啊!而且,这里我们是直接将它编写成了万能颜色选择器,你可以替换任意一种底色,够强大了吧!另外,这里我们只是做了这个小项目的简单演示,我们的运行窗口还是比较单调的,所以如果你有好的创意或者想法,就可以在运行窗口中进行改造,添加自己喜欢的背景图片,或者更换字体、字体颜色、字体大小,窗口大小、按钮背景色,按钮背景图等等任意你喜欢的样式!然后将它包装成exe软件发送给你的朋友,然后他不用安装任何py环境或者库就能完美运行!如何包装exe软件这里不再赘述,也是超级简单,有兴趣的小伙伴可以自行搜索。
码块不易,如果对你有一丝丝的帮助,留言点个赞吧!
下面是全部源码:
from tkinter import *
from removebg import RemoveBg
from tkinter import filedialog
from PIL import Image
from tkinter import colorchooser
import os
#创建窗口
window=Tk()
window.withdraw()
#刷新窗口
window.update()
#窗口标题
window.title('证件照换底工具')
#窗口ico图标
window.iconbitmap('um.ico')#此处需要更换成你自己的ico图标
#窗口不允许更改大小,为了方便设置后续的功能
window.resizable(0,0)
#设置窗口大小
width=520
height=300
#实现窗口自动在电脑屏幕居中
screenwidth=window.winfo_screenwidth()
screenheight=window.winfo_screenheight()
login_size='%dx%d+%d+%d'%(width,height,(screenwidth-width)/2,
(screenheight-height)/2-20)
window.geometry(login_size)
#展示窗口
window.deiconify()
def col():
global colorvalue
root = Toplevel(window)
root.withdraw()
root.update()
root.title('照片底色')
root.iconbitmap('um.ico')
root.resizable(0,0)
width=520
height=300
screenwidth=window.winfo_screenwidth()
screenheight=window.winfo_screenheight()
login_size='%dx%d+%d+%d'%(width,height,(screenwidth-width)/2,
(screenheight-height)/2-20)
window.geometry(login_size)
window.deiconify()
#创建一个自定义选择颜色的面板
colorvalue = colorchooser.askcolor()
#让我们选择的颜色出现在创建的窗口中
label2=Label(font=('Times', 12, 'bold'))
label2['text']=colorvalue
label2.place(x=160,y=65)
#这里我们让这个颜色值在运行窗口中只显示3秒种就隐藏消失
label2.after(3000,label2.destroy)
def open_img():
global img
global filepath
try:
filepath = filedialog.askopenfilename() # 打开文件,返回该文件的完整路径
filename.set(filepath)
img = Image.open(filename.get())
#如果报错就执行:
except Exception as e:
print("没有选择任何文件",e)
def chack():
global new_image
#获取上面函数中我们定义好的照片路径和名称
old_image_path=filepath
#输入我们在removebg官网注册后获取的API Key
api_key="你自己注册获取的API Key"#这里你自己替换吧!
rmbg = RemoveBg(api_key, "error.log")
rmbg.remove_background_from_img_file(old_image_path)
color=colorvalue[0]
parent_path = os.path.dirname(old_image_path)
old_image_name = os.path.split(old_image_path)[-1]
no_bg_image_name = old_image_name + "_no_bg.png"
if no_bg_image_name in os.listdir(parent_path):
no_bg_image_path = parent_path + "/" + no_bg_image_name
no_bg_image = Image.open(no_bg_image_path)
x, y = no_bg_image.size
try:
new_image = Image.new('RGBA', no_bg_image.size, color=color)
new_image.paste(no_bg_image, (0, 0, x, y), no_bg_image)
#如果换底色成功,就在窗口上显示:转换完成,请保存!
label=Label(font=('Times', 12, 'bold'))
label['text']='转换完成,请保存!'
label.place(x=160,y=165)
label.after(3000,label.destroy)
except:
print("except")
else:
print("fail")
def save_png():
try:
filetypes = [("PNG","*.png")]
filenewpath= filedialog.asksaveasfilename(title='保存文件',filetypes=filetypes,
defaultextension='.png',initialdir='C:/Users/Administrator/Desktop' )
path_var.set(filenewpath)
new_image.save(filenewpath)
except Exception as e:
print(e)
#首先,就是设置自定义背景色的功能按钮
filename = StringVar()
path_var = StringVar()
text=Label(window,text="请选择背景色",font=('Times', 14, 'bold'))
#设置文本位置
text.place(x=200,y=20)
#设置按钮位置
Button(window, text="自定义底色", command=col).place(x=320,y=60)
# 然后,设置选择照片和实现底色转换的功能按钮和显示位置
entry = Entry(window, textvariable=filename)
entry.place(x=150,y=115,width=160, height=25)
Button(window, text='选择文件', command=open_img).place(x=332,y=110)
Button(window, text='点击转换', command=chack).place(x=332,y=160)
# 最后,设置保存换底色成功后的照片的功能按钮和显示位置
entry1 = Entry(window, textvariable=path_var)
entry1.place(x=150,y=215,width=160, height=25)
Button(window, text='保存文件', command=save_png).place(x=332,y=210)
window.mainloop()