小程序canvas画图,图片和文字合并成一张图片
async onLoad(ops) { this.makeResImg(); } /** * CANVAS画布生成图片 */ makeResImg() { wx.showLoading({ title: "生成中", mask: true }); this.setCanvasCtx(()=>{ this.makeResImgAfter(); }) }, // setCanvasCtx(callback){ if(this.data.posterCanvas){ console.log(222) this.data.posterCtx.clearRect(0, 0, this.data.posterCanvas.width, this.data.posterCanvas.height); callback && callback(); }else{ console.log(111) const query = wx.createSelectorQuery(); query.select('#makeResCanvas') .fields({ node: true, size: true }) .exec((res) => { // console.log(res); this.setData({ posterCanvas : res[0].node }) this.setData({ posterCtx : this.data.posterCanvas.getContext('2d') }) this.data.posterCtx.clearRect(0, 0, this.data.posterCanvas.width, this.data.posterCanvas.height); callback && callback(); }) } }, // makeResImgAfter(){ // 写入 生成图片 背景图片 const posterBgImg = this.data.posterCanvas.createImage(); posterBgImg.src = 'https://bsy-bs-img-1308012692.cos.ap-guangzhou.myqcloud.com/test/banner/1724643922916.png?sign=q-sign-algorithm%3Dsha1%26q-ak%3DAKIDGtpp0PvWQjS6QkGR3nTDuV9DDc8AFE4t%26q-sign-time%3D1726709145%3B1726710945%26q-key-time%3D1726709145%3B1726710945%26q-header-list%3Dhost%26q-url-param-list%3D%26q-signature%3D3b6f05b5c3059356dbdd1063d88da22035882f59'; // this.getDownloadFile('https://xxxxxxxxx/poster_bg.png',(formimgTempFilePath)=>{ // posterBgImg.src = formimgTempFilePath; posterBgImg.onload = () => { console.log('背景图实际宽高', posterBgImg.width, posterBgImg.height); this.data.posterCanvas.width = posterBgImg.width; this.data.posterCanvas.height = posterBgImg.height; this.setData({ makeResCanvasW:0, makeResCanvasH:0, }) // 画入背景图片 this.data.posterCtx.drawImage(posterBgImg, 0, 0, posterBgImg.width, posterBgImg.height); // 写入 生成图片 勾选标识图片 const checkImg = this.data.posterCanvas.createImage(); checkImg.src = 'https://bsy-bs-img-1308012692.cos.ap-guangzhou.myqcloud.com/test/sellerGoods/1688108045196.png?sign=q-sign-algorithm%3Dsha1%26q-ak%3DAKIDGtpp0PvWQjS6QkGR3nTDuV9DDc8AFE4t%26q-sign-time%3D1726711227%3B1726713027%26q-key-time%3D1726711227%3B1726713027%26q-header-list%3Dhost%26q-url-param-list%3D%26q-signature%3D092789981663c6b89870497b9bacb7ad207ae84e'; // this.getDownloadFile('https://xxxxxxxxx/check.png',(checkTempFilePath)=>{ // checkImg.src = checkTempFilePath; checkImg.onload = () => { // 画入勾选标识图片 // this.data.posterCtx.drawImage(checkImg, 20, 188, 32, 24); // this.data.posterCtx.drawImage(checkImg, 20 + 42, 188, 32, 24); // this.data.posterCtx.drawImage(checkImg, 20 + 42 + 42, 188, 32, 24); // this.data.posterCtx.drawImage(checkImg, 20 + 42 + 42 + 42, 188, 32, 24); // this.data.posterCtx.drawImage(checkImg, 20 + 42 + 42 + 42 + 42, 188, 32, 24); // this.data.posterCtx.drawImage(checkImg, 20 + 42 + 42 + 42 + 42 + 42, 188, 32, 24); // 文字背景块 this.data.posterCtx.drawImage(checkImg, 10, 60, 180, 40); // 写入文本 this.data.posterCtx.fillStyle = '#000000'; this.data.posterCtx.textAlign = 'left'; this.data.posterCtx.textBaseline = 'top'; this.data.posterCtx.font = '26px "PingFangSC-Regular","STHeitiSC-Light","微软雅黑","Microsoft YaHei","sans-serif"'; // 写入单行文本 this.data.posterCtx.fillText('写入单行文本',10,60); // 写入多行文本 this.writeTextOnCanvas(this.data.posterCtx, 36, 40, '写入多行文本写入多行文本写入多行文本写入多行文本写入多行文本写入多行文本' ,10, 100); // 生成图片 this.setData({ posterUrl: this.data.posterCanvas.toDataURL('image/png'), }) console.log('图片啊啊啊啊啊啊啊啊啊啊') console.log(this.data.posterUrl) // 查看生成的图片 setTimeout(()=>{ wx.previewImage({ current: this.data.posterUrl, urls: [this.data.posterUrl] }); },10) wx.hideLoading(); // base64图片保存至相册 setTimeout(()=>{ this.base64ImageHandle(this.data.posterUrl); },10) } // }) } // }) }, // 写入多行文本 writeTextOnCanvas(ctx_2d, lineheight, bytelength, text ,startleft, starttop){ function getTrueLength(str){ var len = str.length, truelen = 0; for(var x = 0; x < len; x++){ if(str.charCodeAt(x) > 128){ truelen += 2; }else{ truelen += 1; } } return truelen; } function cutString(str, leng){ var len = str.length, tlen = len, nlen = 0; for(var x = 0; x < len; x++){ if(str.charCodeAt(x) > 128){ if(nlen + 2 < leng){ nlen += 2; }else{ tlen = x; break; } }else{ if(nlen + 1 < leng){ nlen += 1; }else{ tlen = x; break; } } } return tlen; } for(var i = 1; getTrueLength(text) > 0; i++){ var tl = cutString(text, bytelength); ctx_2d.fillText(text.substr(0, tl).replace(/^\s+|\s+$/, ""), startleft, (i-1) * lineheight + starttop); text = text.substr(tl); } }, // 下载网络图片 getDownloadFile(img,callback){ wx.downloadFile({ url: img, success (res) { if (res.statusCode === 200) { callback && callback(res.tempFilePath) } } }) }, // base64图片保存至相册 base64ImageHandle(base64) { // 指定图片的临时路径 const path = `${wx.env.USER_DATA_PATH}/reportformImg.png` console.log("path") console.log(path) // 获取小程序的文件系统 const fsm = wx.getFileSystemManager() // 把arraybuffer数据写入到临时目录中 fsm.writeFile({ filePath: path, data: base64.replace(/^data:image\/\w+;base64,/, ''), encoding: 'base64', success: () => { wx.hideLoading(); wx.showModal({ title: '保存图片', content: '保存数据报表图片至手机相册?', success: (result) => { if (result.confirm) { // 把临时路径下的图片,保存至相册 wx.saveImageToPhotosAlbum({ filePath: path, success: () => { wx.showToast({ title: '保存海报成功', icon: 'success', duration: 2000 }) } }) } } }) } }) },
js
data: { makeResCanvasW : 0, makeResCanvasH : 0, }
wxml
<canvas type="2d" id="makeResCanvas" style="width: {{makeResCanvasW}}rpx;height: {{makeResCanvasH}}rpx;"></canvas>
====================================================================================
以下仅仅是小工具,跟图片合并无关,跟画图无关,无关!!
//base64转换成图片 getBase64ImageUrl: function(data) { /// 获取到base64Data var base64Data = data; /// 通过微信小程序自带方法将base64转为二进制去除特殊符号,再转回base64 base64Data = wx.arrayBufferToBase64(wx.base64ToArrayBuffer(base64Data)); /// 拼接请求头,data格式可以为image/png或者image/jpeg等,看需求 const base64ImgUrl = "data:image/png;base64," + base64Data; /// 刷新数据 return base64ImgUrl; }, getToLocal(){ var base64data = this.data.posterUrl; // base64 const fsm = wx.getFileSystemManager(); const FILE_BASE_NAME = 'tmp_base64src'; //自定义文件名 const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || []; if (!format) { return (new Error('ERROR_BASE64SRC_PARSE')); } const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`; const buffer = wx.base64ToArrayBuffer(bodyData); fsm.writeFile({ filePath, data: buffer, encoding: 'binary', success(r) { console.log(r,'r') console.log(filePath,'filePath') }, fail() { return (new Error('ERROR_BASE64SRC_WRITE')); }, }); },