电子签名如何解决生成的图片为空白的问题,以及生成透明底签名图片转为白色底
一、生成的图片为空白
项目有个新需求需要加电子签名,在实现的过程中遇到了许多问题,现用的插件笔画延迟非常严重,好不容易做完之后又得换一个插件;换了之后又发现画完图后产生的图片是空白的,百度之后才知道,生成图片调用的 uni.canvasToTempFilePath 接口必须要在 draw()回调使用
并且需要异步调用,在图片生成好之后再将它上传到服务器上,否则上传之后回显的图片就是空白的。
在 useCanvans.js 文件里
// 生成图片调用的uni.canvasToTempFilePath接口必须要在draw()回调使用,
// 否则可能生成空白图片,异步方法保证等待图片完成了再上传到服务器
function saveCanvas() {
return new Promise((resolve, rej) => {
params.ctx.draw(
true,
createFileUrl().then((res) => {
resolve(res);
})
);
});
}
function createFileUrl() {
return new Promise((resolve, rej) => {
uni.canvasToTempFilePath({
canvasId: 'handWriting',
fileType: 'png',
quality: 1, //图片质量
success(res) {
console.log(res.tempFilePath, 'canvas生成图片地址');
resolve(res.tempFilePath);
},
fail: function (err) {
console.log('图片生成失败:' + err);
},
});
});
}
在需要调用生成图片 api 的文件里异步调用:
saveCanvas().then((res) => {
console.log(
'%c [ tempFilePath ]',
'font-size:13px; background:pink; color:#bf2c9f;',
res
);
wx.uploadFile({...});
});
二、透明底签名图片转为白色底
第一次尝试
使用第二个插件中,有一个函数的注释说明转背景为白色,但是引入这个插件后生成的图片却还是透明的
onLoad() {
this.ctx = uni.createCanvasContext("handWriting");
this.$nextTick(() => {
uni.createSelectorQuery().select('.handCenter').boundingClientRect(rect => {
this.canvasWidth = rect.width;
this.canvasHeight = rect.height;
/* 将canvas背景设置为 白底,不设置 导出的canvas的背景为透明 */
this.setCanvasBg('#fff');
})
.exec();
});
},
//设置canvas背景色 不设置 导出的canvas的背景为透明
//@params:字符串 color
setCanvasBg(color) {
/* 将canvas背景设置为 白底,不设置 导出的canvas的背景为透明 */
//rect() 参数说明 矩形路径左上角的横坐标,左上角的纵坐标, 矩形路径的宽度, 矩形路径的高度
//这里是 canvasHeight - 4 是因为下边盖住边框了,所以手动减了写
this.ctx.rect(0, 0, this.canvasWidth, this.canvasHeight - 4);
// ctx.setFillStyle('red')
this.ctx.setFillStyle(color);
this.ctx.fill(); //设置填充
this.ctx.draw(); //开画
}
第二次尝试
一开始还以为是我理解错了,上面那个方法不是转白色底方法,于是又去网上找了其他方法:使用 wx.canvasGetImageData 和 wx.canvasPutImageData 改变图片的底色。
function toWhite() {
console.log(
'%c [ width ]',
'font-size:13px; background:pink; color:#bf2c9f;'
);
wx.canvasGetImageData({
canvasId: 'handWriting',
x: 0,
y: 0,
width: params.canvasWidth,
height: params.canvasHeight,
success(res) {
console.log(res.width); // 100
console.log(res.height); // 100
console.log(res.data instanceof Uint8ClampedArray); // true
console.log(res.data.length); // 100 * 100 * 4
var imageData = res.data;
for (var i = 0; i < imageData.length; i += 4) {
// 当该像素是透明的,则设置成白色
if (imageData[i + 3] === 0) {
imageData[i] = 255;
imageData[i + 1] = 255;
imageData[i + 2] = 255;
imageData[i + 3] = 255;
}
}
wx.canvasPutImageData({
canvasId: 'handWriting',
x: 0,
y: 0,
width: params.canvasWidth,
height: params.canvasHeight,
data: imageData,
success(res) {
console.log(
'%c [ toWhite ]',
'font-size:13px; background:pink; color:#bf2c9f;',
res
);
},
});
},
});
}
尝试过后发现还是不行,调试的错误信息显示传入的 width 为 0,这才发现前面获取宽高失败了,于是写死传入的宽高尝试了一下,发现还是不可以,但是让我想明白了为什么第一次尝试失败,也是因为在 setCanvasBg 函数中传入的宽高为 0。文章来源:https://www.toymoban.com/news/detail-485036.html
this.ctx.rect(0, 0, this.canvasWidth, this.canvasHeight - 4);
传入正确的宽高之后果然成功了,但是要注意如果宽高是动态的话,一定要在设置底色前将宽高获取,否则生成的第一张签名还是透明底。
但是还是不明白为什么在初始化时获取宽高失败,很可能是由于this.$nextTick内的代码没有成功执行。文章来源地址https://www.toymoban.com/news/detail-485036.html
到了这里,关于电子签名生成的图片为空白,以及生成透明底签名图片转为白色底的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!