1. 资源准备

①海报背景图(建议不要放置在本地),

② 头像(需授权),

③附参考二维码,

④需要定制的文字和小图标图片

2. 工具和方法

① 将rpx转换为与屏幕尺寸兼容的px的方法(手机屏幕不同,canvas以px为单位)

functioncreateRpx2px(){
 const{ windowWidth }= wx.getSystemInfoSync()
 returnfunction(rpx){
 return windowWidth /750* rpx
 }
 }

 

②将base64图片保存到本地并返回本地文件路径(二维码返回base64)

const fsm = wx.getFileSystemManager();
constFILE_BASE_NAME='tmp_base64src';
exportconstbase64src=function(base64data){
 returnnewPromise((resolve, reject)=>{
 let time =newDate().getTime()
 let[, format, bodyData]=/data:image\/(\w+);base64,(.*)/.exec(base64data)[];
 if(!format){
 reject(newError('ERROR_BASE64SRC_PARSE'));
 }
 //加时间戳是为了图片的缓存问题
 let filePath =`${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME+time}.${format}`;
 console.log(filePath)
 let buffer = wx.base64ToArrayBuffer(bodyData);
 console.log(buffer)
 fsm.writeFile({
 filePath,
 data: buffer,
 encoding:'binary',
 success(){
 resolve(filePath);
 },
 fail(){
 reject(newError('ERROR_BASE64SRC_WRITE'));
 },
 });
 });
};

 

③获取图片,获取本地地图、网络地图信息=>提供用于绘图canvasy

getImageInfo(url){
 returnnewPromise((resolve, reject)=>{
 wx.getImageInfo({
 src: url,
 success(res){
 //如果是本地图片的话此api返回的路径有问题,所以需要判断是否是网络图片
 if(!/^https/.test(url)){
 res.path = url
 };
 resolve(res)
 },
 fail(err){
 console.log('errimgurl', err)
 reject(err.errMsg +`${url}`)
 },
 })
 })
 },

 

④ 计算文字长度(绘制画布时,定位是根据左上角的距离,如果想在同一行文字旁边绘制其他图形和文字,则需要计算文字长度)

// 计算文本长度
 calcTextLength(text){
 let len =0
 for(let i =0;i<text.length;i++){
 if(text.charCodeAt(i)>255){
 len +=2
 }else{
 len +=1
 }
 }
 return len*15
 },

 

⑤画一个圆形图。 一般来说,头像需要画成圆形。

/**
 *
 * @param {*} contex
 * @param {绘制的头像} img
 * @param {x坐标} x
 * @param {y坐标} y
 * @param {直径} d
 */
 circleImg(contex, img, x, y, d){
 let avatarurl_width = d;//绘制的头像宽度
 let avatarurl_heigth = d;//绘制的头像高度
 contex.save();
 contex.beginPath();//开始绘制
 //先画个圆 前两个参数确定了圆心 (x,y) 坐标 第三个参数是圆的半径 四参数是绘图方向 默认是false,即顺时针
 contex.arc(avatarurl_width /2+ x, avatarurl_heigth /2+ y, d /2,0, Math.PI*2,false);
 contex.clip();//画好了圆 剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内 这也是我们要save上下文的原因
 contex.drawImage(img, x, y, avatarurl_width, avatarurl_heigth);// 推进去图片,必须是https图片
 contex.stroke();
 contex.closePath();
 contex.restore();//恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 还可以继续绘制
 
 },

 

	/**
 *
 *保存canvas绘制的图像到临时目录
 */
 canvasToTempFilePath(option, context){
 returnnewPromise((resolve, reject)=>{
 wx.canvasToTempFilePath({
 ...option,
 success: resolve,
 fail(){
 console.log('canvasToTempFilePath', err)
 reject(err)
 },
 }, context)
 })
 },

 

⑦ 获取二维码

getcodeImg(){
 let data ={
 "width":430,
 "scene":`c=${productCode}&j=${jobNumber}&m=${productModel}`//二维码的参数
 }
 if(process.env.NODE_ENV==='production'){
 data.page ="pages/index/index"
 }
 console.log('二维码参数', data)
 returnnewPromise((reslove, reject)=>{
 app.$Http.post('/api/agentInfo/codeUnlimit', data).then(res =>{
 console.log('二维码res', res)
 let base64 = res.content
 let src =`data:image/png;base64,${base64}`
 reslove(src)
 }).catch(err =>{
 console.log('二维码err', err)
 reject(err)
 })
 })
}

 

3 生成海报

下面画的只是一个想法。 具体来说,需要自带海报需求。 基本的海报功能基本可以满足。

<viewclass="warp">
 
 <canvasclass="canvas-hide"style="width: 686rpx;height: 1064rpx;"canvas-id="share">canvas>
 <imagesrc="{{imgsrc}}"alt=""style="width: 686rpx;height: 1064rpx;"bindtap="previewImage"/>
 {imgsrc}}" >保存到相册 -->
 
 view>

 

.canvas-hide{
 position: fixed;
 top: 0;
 left: 0;
 transform:translateX(-100%);
 width: 654rpx;
 height: 1010rpx;
}

 

drawCanvas(){
 //图片地址可以是本地相对路。

 

作者 admin