前言
无论是我们上学时还之后的工作中,基本都需要用到电子证件照片,这类照片基本都对照片尺寸、背景色有要求,本文我们来看一下如何只用不到 20 行 Python 代码完成证件照片的制作。
简介
哈喽~大家好,欢迎来到每日小技巧,今天来教大家如何使用Python制作精美证件照,说到制作精美证件照的方法,可能不会Python的小伙伴首先想到的是美图秀秀,或者使用photoshop,也有人首先想到的是第三方接口(如:百度AI),但是作为Python爱好者,怎么能不会用Python制作精美证件照呢~
下面就开始介绍两种免费去除照片背景的方法
第一种
第一种方法是:removebg(实际上还是第三方接口,不过removebg是免费的)
remove官方地址:
首先先注册一个账号,然后访问下方链接获取api_keys(代码里面会用到)
https://www.remove.bg/api#remove-background
点击Get API Key 即可获取key值
获取到key值后,咱们就开编写python程序
# 导入库 from removebg import RemoveBg api_keys = "上面获取到的key值" rmbg = RemoveBg(api_key, "error.log") #rmbg.remove_background_from_img_file("图片路径") rmbg.remove_background_from_img_file("chen.jpg")
样例效果:
(图片来源网络)
总结
优点:不限于证件照,任何图片都可以去除背景(包括全身照片以及多人合影照片等)
缺点:这个方法只能免费使用50次,超过50次就会提示报错(如下所示)
第二种
第二种方法就是backgroundremover,其实就是一个Python库
github地址:
https://github.com/nadermx/backgroundremover
使用很简单:就两步(github介绍安装中有一些没必要安装,可忽略)
第一步:安装库
pip install backgroundremover
第二步:执行命令
# backgroundremover -i "带背景照片" -o "去除背景照片" backgroundremover -i "cg.jpg" -o "cg_outopt.jpg"
Python方式调用:
# 导入库 import os os.system('backgroundremover -i "cg.jpg" -o "cg_output.jpg"')
原理:实际上就是python通过os去执行终端命令。
注意:
在第二步时,初次使用需要下载模型(大概170m),下载地址是google,因此需要能够访问google,才能下载。
不过不用担心,大家评论区回复:Python,我会发放给你们哒~
下载好的模型需要放到当前系统用户的目录下:
## Window: c:/Windows/user/.u2net/u2net.pth ## Mac: /Users/lyc/.u2net/u2net.pth ## Linux: /root/.u2net/u2net.pth
样例效果:
(图片来源于网络)
同一张照片,使用这两种不同的方法去除背景
效果差别不大(推荐第二种方法)
总结
优点:不限次数使用,不仅可以对照片去除背景,还可以对视频去除背景(github上有使用方法,感兴趣的可以去看看)
对比这两种方法,比较推荐使用第二种,理由:完全免费、功能多。
制作精美证件照代码实战
环境准备
pip install opencv-python
pip install removebg
这里去除照片背景色功能,我们先使用removebg方式来实现,如果有兴趣,自己可以
可以使用第二种方式来实现。
我们使用removebg来去除背景色,在使用opencv-python来更改图像背景色
#修改背景色 def change_bgcolor(file_in, file_out, color): ''' #必须为png格式 ''' try: if not os.path.exists('outs'): os.mkdir('outs') if not file_in.endswith('.png'): newfile = file_in.lower().replace('jpg', 'png') os.rename(file_in, newfile) file_in = newfile p, s = file_in.split(".") rmbg = RemoveBg(api_key, 'error.log') rmbg.remove_background_from_img_file(file_in) file_no_bg = "{}.{}_no_bg.{}".format(p, s, s) no_bg_image = Image.open(file_no_bg) # no_bg_image.show() x, y = no_bg_image.size new_image = Image.new('RGBA', no_bg_image.size, color=color) new_image.paste(no_bg_image, (0, 0, x, y), no_bg_image) new_image.save(f'outs/{file_out}') if not os.path.exists(f'outs/{p}_nobg.png'): os.rename(file_no_bg, f'outs/{p}_nobg.png') except: pass
处理图像大小函数:
#修改图像大小 def change_size(file_in, file_out, size): try: image = Image.open(f'outs/{file_in}') resized_image = image.resize(size, Image.ANTIALIAS) resized_image.save(f'outs/{file_out}') except: pass
以上就是制作证件照的核心功能了,下面在来写一个py文件来完成GUI程序的制作。
GUI窗口程序开发
GUI窗口这里使用的是Pyqt5这个包
定义窗口程序类:
class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(540, 561) MainWindow.setFixedSize(560, 561) MainWindow.setWindowIcon(QIcon("./logo.ico")) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget) self.pushButton_2.setGeometry(QtCore.QRect(120, 40, 321, 51)) self.pushButton_2.setStyleSheet("border:1px solid rgb(0, 170, 127);\n" "background-color: rgb(0, 170, 127);\n" "border-radius:45px;\n" "font: 15pt \"Corbel\";\n" "color:blue;") self.pushButton_2.setObjectName("pushButton_2") self.label = QtWidgets.QLabel(self.centralwidget) self.label.setGeometry(QtCore.QRect(40, 120, 72, 15)) self.label.setObjectName("label") self.comboBox = QtWidgets.QComboBox(self.centralwidget) self.comboBox.setGeometry(QtCore.QRect(120, 110, 321, 31)) self.comboBox.setObjectName("comboBox") self.comboBox_2 = QtWidgets.QComboBox(self.centralwidget) self.comboBox_2.setGeometry(QtCore.QRect(120, 150, 321, 31)) self.comboBox_2.setObjectName("comboBox_2") self.label_2 = QtWidgets.QLabel(self.centralwidget) self.label_2.setGeometry(QtCore.QRect(40, 160, 72, 15)) self.label_2.setObjectName("label_2") self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget) self.pushButton_3.setGeometry(QtCore.QRect(80, 200, 391, 51)) self.pushButton_3.setStyleSheet("border:1px solid rgb(255, 170, 0);\n" "selection-color: rgb(170, 170, 255);\n" "background-color: rgb(255, 170, 0);\n" "border-radius:23px;\n" "font: 15pt \"Corbel\";\n" "color:blue;") self.pushButton_3.setObjectName("pushButton_3") self.groupBox = QtWidgets.QGroupBox(self.centralwidget) self.groupBox.setGeometry(QtCore.QRect(50, 270, 431, 191)) self.groupBox.setObjectName("groupBox") self.textBrowser = QtWidgets.QTextBrowser(self.groupBox) self.textBrowser.setGeometry(QtCore.QRect(10, 30, 411, 151)) self.textBrowser.setObjectName("textBrowser") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 540, 26)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "证件照制作工具")) self.pushButton_2.setText(_translate("MainWindow", "选择图片")) self.label.setText(_translate("MainWindow", "尺寸选择:")) self.comboBox.setToolTip(_translate("MainWindow", "123")) self.label_2.setText(_translate("MainWindow", "底色选择:")) self.pushButton_3.setText(_translate("MainWindow", "开始制作")) self.groupBox.setTitle(_translate("MainWindow", "运行日志:"))
窗口程序类已经写好了,现在我们再来定义一个app启动类,用于GUI窗口程序的显示及对应信号槽事件功能的绑定。
app类初始化方法:
class App: def __init__(self): app = QtWidgets.QApplication(sys.argv) MainWindow = QtWidgets.QMainWindow() self.ui = Ui_MainWindow() self.ui.setupUi(MainWindow) self.ui.comboBox.currentTextChanged.connect(self.comboboxOnChange) self.ui.comboBox_2.currentTextChanged.connect(self.combobox2OnChange) self.ui.comboBox.addItems(['标准1寸(295px*413px)', '小1寸(259px*377px)', '2寸(413px*625px)', '大1寸(389px*466px)', '标准2寸(413px*579px)', '小2寸(413px*531px)', '3寸(650px*992px)', '5寸生活照(1050px*1500px)', '结婚照(472px*708px)', '结婚合照(625px*413px)', '社保卡照(358px*441px)', '电子驾照(520px*760px)', '身份证(358px*441px)', '大学生图像信息采集(480px*640px)' , '公务员国考(413px*579px)', '考研(390px*567px)' , '计算机等级考试(144px*192px)', '教师资格证(114px*156px)', ]) self.ui.comboBox_2.addItems(['白色', '红色', '蓝色']) self.ui.pushButton_2.clicked.connect(self.choose_photo) self.ui.pushButton_3.clicked.connect(self.make_photo) MainWindow.show() sys.exit(app.exec_())
选择图片按钮信号槽处理方法:
def choose_photo(self): top = tkinter.Tk() top.geometry('0x0+999999+0') filetypes = ( ('img files', '*.jpg;*.png'), ('All files', '*.*') ) result = filedialog.askopenfile(title='选择图片', initialdir='./', filetypes=filetypes) # print(res.name) self.fname = result.name self.ui.textBrowser.append(f'选择文件:{self.fname.split("/")[-1]}') top.destroy()
尺寸选择于底色选择信号槽处理事件:
def comboboxOnChange(self): text = self.ui.comboBox.currentText() self.ui.textBrowser.append(f'尺寸选择:{text}') def combobox2OnChange(self): text = self.ui.comboBox_2.currentText() self.ui.textBrowser.append(f'底色选择:{text}')
开始制作按钮信号槽处理事件:
def make_photo(self): self.ui.textBrowser.append('开始制作……') file_out = {'白色': 'white', '红色': 'red', '蓝色': "blue"} cb1 = re.findall('(.*?)', self.ui.comboBox.currentText())[0].split('*') # 使用正则提取下拉框的证件照的尺寸 size = ( int(re.sub('(|px|)', '', cb1[0])), int(re.sub('(|px|)', '', cb1[1])), ) # 底色映射 color = { '红色': (255, 0, 0), '蓝色': (0, 112, 192), '白色': (255, 255, 255), } com2text = self.ui.comboBox_2.currentText() file_out = file_out[com2text] + '.png' # print(self.fname, file_out, size) change_bgcolor(self.fname, file_out, color=color[com2text]) change_size(file_out, file_out, size=size) self.ui.textBrowser.append('制作成功!') top = tkinter.Tk() top.geometry('0x0+999999+0') messagebox.showinfo('提示', '制作完成!') top.destroy()
启动app:
if __name__ == "__main__": app = App()
GUI效果图: