项目场景:
通过上传普通签名照片,自动转换成电子签名样式问题描述:
一开始的想法是自动生成电子签名图片,但是不符合某些特定的业务场景,于是换另一个思路,上传真实手写笔迹签名照片,转换电子签名,业主果然满意,于是去了趟厕所(灵感爆发地),稍加思索,便有了初步的解决思路,将上传的图片,读出base64 位编码,转化为numpy array格式的图像,签名是黑色区域,像素值接近0。背景区域转换为纯白色。初版代码:
def button_download(self):
if self.autograph:
path = tools.config.filestore(self._cr.dbname) # 获取附件存储路径
user_id = self.env['ir.attachment'].sudo().search([('res_model', '=', 'res.users'), ('res_id', '=', self.id), ('res_field', '=', 'autograph')])
path += '/' + user_id.store_fname # ir_attachment 所记录的文件夹和文件路径
image = cv2.imread(path, cv2.IMREAD_UNCHANGED)
size = image.shape
for i in range(size[0]):
for j in range(size[1]):
if image[i][j][0] > 100 and image[i][j][1] > 100 and image[i][j][2] > 100:
image[i][j][3] = 0
else:
image[i][j][0], image[i][j][1], image[i][j][2] = 0, 0, 0
image_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
image_path += "\\static\\image\\ss.png"
cv2.imwrite(image_path, image)
with open(image_path, "rb") as imageFile:
str = base64.b64encode(imageFile.read())
self.autograph = str
else:
raise UserError("警告:请用户: %s 上传签名图片 !" % self.name)
原因分析:
初版代码是符合一般图片的,比如ps 生成的图片,签名软件usb 设备上面手写的图片。但是,业主不会这么规范,会出现在白纸上写签名,拍照裁剪的情况。手机拍摄的图片是没有 shape 的第三个元素,位深的。这样,我的代码在 for i 循环的这里会执行不下去的,只有[i][j],没有后续的数组内容。解决方案:
于是又去了趟厕所(灵感爆发地),如果没有深度我就手动给它创建一个深度,将图片处理到我想要的样子。做个判断,二版代码如下:
def button_download(self):
if self.autograph:
path = tools.config.filestore(self._cr.dbname)
user_id = self.env['ir.attachment'].sudo().search([('res_model', '=', 'res.users'), ('res_id', '=', self.id), ('res_field', '=', 'autograph')])
path += '/' + user_id.store_fname
image = cv2.imread(path, cv2.IMREAD_UNCHANGED)
size = image.shape
width = size[0] # 宽度
height = size[1] # 高度
if size[2] != 4: # 判断
background = np.zeros((size[0], size[1], 4))
for yh in range(height):
for xw in range(width):
background[xw, yh, :3] = image[xw, yh]
background[xw, yh, 3] = 255
image = background
size = image.shape
for i in range(size[0]):
for j in range(size[1]):
if image[i][j][0] > 100 and image[i][j][1] > 100 and image[i][j][2] > 100:
image[i][j][3] = 0
else:
image[i][j][0], image[i][j][1], image[i][j][2] = 0, 0, 0
image_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
image_path += "\\static\\image\\ss.png"
cv2.imwrite(image_path, image)
with open(image_path, "rb") as imageFile:
str = base64.b64encode(imageFile.read())
self.autograph = str
else:
raise UserError("警告:请用户: %s 上传签名图片 !" % self.name)
实操视频
生成电子签名