150行代码生成自定义身份证图片

Դ未知

ߣ老铁SEO

10

2019-05-21 16:55:58

背景

现在越来越多的账号要求实名,有时会要求上传身份证图片。利用此程序可以生成一个自定义信息的身份证图片,避免自己的信息被泄漏。(P.S. 亲测可以通过Facebook的账号解锁认证。)

程序

编写语言为python,兼容python2和python3,跨平台使用

使用tkinter绘制软件界面 root = Tk() root.resizable(width=False, height=False) Label(root, text=u'姓名:').grid(row=0, column=0, sticky=W, padx=3, pady=3) ename = Entry(root, width=8) ename.grid(row=0, column=1, sticky=W, padx=3, pady=3) Label(root, text=u'性别:').grid(row=0, column=2, sticky=W, padx=3, pady=3) esex = Entry(root, width=8) esex.grid(row=0, column=3, sticky=W, padx=3, pady=3) Label(root, text=u'民族:').grid(row=0, column=4, sticky=W, padx=3, pady=3) enation = Entry(root, width=8) enation.grid(row=0, column=5, sticky=W, padx=3, pady=3) Label(root, text=u'出生年:').grid(row=1, column=0, sticky=W, padx=3, pady=3) eyear = Entry(root, width=8) eyear.grid(row=1, column=1, sticky=W, padx=3, pady=3) Label(root, text=u'月:').grid(row=1, column=2, sticky=W, padx=3, pady=3) emon = Entry(root, width=8) emon.grid(row=1, column=3, sticky=W, padx=3, pady=3) Label(root, text=u'日:').grid(row=1, column=4, sticky=W, padx=3, pady=3) eday = Entry(root, width=8) eday.grid(row=1, column=5, sticky=W, padx=3, pady=3) Label(root, text=u'住址:').grid(row=2, column=0, sticky=W, padx=3, pady=3) eaddr = Entry(root, width=32) eaddr.grid(row=2, column=1, sticky=W, padx=3, pady=3, columnspan=5) Label(root, text=u'证件号码:').grid(row=3, column=0, sticky=W, padx=3, pady=3) eidn = Entry(root, width=32) eidn.grid(row=3, column=1, sticky=W, padx=3, pady=3, columnspan=5) Label(root, text=u'签发机关:').grid(row=4, column=0, sticky=W, padx=3, pady=3) eorg = Entry(root, width=32) eorg.grid(row=4, column=1, sticky=W, padx=3, pady=3, columnspan=5) Label(root, text=u'有效期限:').grid(row=5, column=0, sticky=W, padx=3, pady=3) elife = Entry(root, width=32) elife.grid(row=5, column=1, sticky=W, padx=3, pady=3, columnspan=5) Label(root, text=u'选项:').grid(row=6, column=0, sticky=W, padx=3, pady=3) ebgvar = IntVar() ebg = Checkbutton(root, text=u'自动抠图', variable=ebgvar) ebg.grid(row=6, column=1, sticky=W, padx=3, pady=3, columnspan=5) Button(root, text=u'生成', width=32, command=generator).grid(row=7, column=1, sticky=W, padx=3, pady=3, columnspan=4)

加载对应字体,画在特定位置上

按照参照标准加载对应字体

正面

“姓名”、“性别”、“民族”、“出生年月日”、“住址”、“公民身份号码”为6号黑体字,用蓝色油墨印刷;登记项目中的姓名项用5号黑体字印刷;其他项目则用小5号黑体字印刷;出生年月日 方正黑体简体字符大小:姓名+号码(11点)其他(9点)字符间距(AV):号码(50)字符行距:住址(12点);身份证号码字体 OCR-B 10 BT 文字 华文细黑。

背面

左上角为国徽,用红色油墨印刷;其右侧为证件名称“中华人民共和国居民身份证”,分上下两排排列,其中上排的“中华人民共和国”为4号宋体字,下排的“居民身份证”为2号宋体字;“签发机关”、“有效期限”为6号加粗黑体字;签发机关登记项采用,“xx市公安局”;有效期限采用“xxxx.xx-xxxx.xx.xx”格式,使用5号黑体字印刷,全部用黑色油墨印刷。

draw = ImageDraw.Draw(im) draw.text((630, 690), name, fill=(0, 0, 0), font=name_font) draw.text((630, 840), sex, fill=(0, 0, 0), font=other_font) draw.text((1030, 840), nation, fill=(0, 0, 0), font=other_font) draw.text((630, 980), year, fill=(0, 0, 0), font=bdate_font) draw.text((950, 980), mon, fill=(0, 0, 0), font=bdate_font) draw.text((1150, 980), day, fill=(0, 0, 0), font=bdate_font) start = 0 loc = 1120 while start + 11 < len(addr): # 循环用于一行显示不下情况下换行 draw.text((630, loc), addr[start:start + 11], fill=(0, 0, 0), font=other_font) start += 11 loc += 100 draw.text((630, loc), addr[start:], fill=(0, 0, 0), font=other_font) draw.text((950, 1475), idn, fill=(0, 0, 0), font=id_font) draw.text((1050, 2750), org, fill=(0, 0, 0), font=other_font) draw.text((1050, 2895), life, fill=(0, 0, 0), font=other_font) 抠图

把图像转换为opencv使用的BGR通道

avatar = cv2.cvtColor(np.asarray(avatar), cv2.COLOR_RGB2BGR) im = cv2.cvtColor(np.asarray(im), cv2.COLOR_RGB2BGR) if ebgvar.get(): # 如果使用自动抠图 im = changeBackground(avatar, im, (500, 670), (690, 1500)) else: # 如果不使用自动抠图 # im.paste(avatar, (1500, 690), mask=avatar) im = paste(avatar, im, (500, 670), (690, 1500)) im = PImage.fromarray(cv2.cvtColor(im, cv2.COLOR_BGR2RGB))

替换背景

def changeBackground(img, img_back, zoom_size, center): # 缩放 img = cv2.resize(img, zoom_size) rows, cols, channels = img.shape # 转换hsv,HSV(hue,saturation,value)颜色空间的模型对应于圆柱坐标系中的一个圆锥形子集 # 它重新影射了RGB模型,从而能够视觉上比RGB模型更具有视觉直观性 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 获取mask lower_blue = np.array([78, 43, 46]) # 蓝色取值下界 upper_blue = np.array([110, 255, 255]) # 蓝色取值上届 mask = cv2.inRange(hsv, lower_blue, upper_blue) # 去除蓝色背景 # cv2.imshow('Mask', mask) # 腐蚀膨胀,防止图片锯齿感 erode = cv2.erode(mask, None, iterations=1) dilate = cv2.dilate(erode, None, iterations=1) # 把去除背景的头像画在另一张背景上 for i in range(rows): for j in range(cols): if dilate[i, j] == 0: # 0代表黑色的点 img_back[center[0] + i, center[1] + j] = img[i, j] # 此处替换颜色,为BGR通道 return img_back

覆盖至指定位置

def paste(avatar, bg, zoom_size, center): avatar = cv2.resize(avatar, zoom_size) # 改变大小 rows, cols, channels = avatar.shape for i in range(rows): for j in range(cols): bg[center[0] + i, center[1] + j] = avatar[i, j] # 画在指定位置 return bg 使用说明

填入信息,选择一张头像图片(即可生成黑白和彩色身份证图片)

可以选择是否自动抠图,自动抠图目前仅支持蓝色背景,对自动抠图效果不满意可以手动抠图。

在线抠图地址:https://burner.bonanza.com/

准备一个寸照

结果

示范样例

高清传送门

下载&&github

Windows下载

Mac下载

github

*本文作者:anymous

佭ϴý Ѷ Media8ý

在线客服

外链咨询

扫码加我微信

微信:juxia_com

返回顶部