主要实现三个功能,要使用canvas生成海报,包含动态生成的小程序码,然后将海报保存到相册。
这里使用的是uniapp 实现微信小程序 生成海报
第一:canvas生成海报
//视图块
<view class="pc-container" @longpress="saveImage">
<canvas canvas-id="mycanvas" style="width: 300px;height: 500px;" class="canvas-wrapper"></canvas>
</view>
//样式
.pc-container {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(0,0,0,0.5);
}
.canvas-wrapper{
background-color: #FFFFFF;// 在这里设置海报的白色 背景 是无效的,注意!!!必须通过代码设置
width: 100%;
box-sizing: border-box;
min-height: 996rpx;
}
直接调用这个方法就可以了,海报可以生成了,自定义的图片 文字 小程序码
canvasImage() {
let myCanvas = uni.createCanvasContext('mycanvas');
//画布尺寸
// 坐标(0,0) 表示从此处开始绘制,相当于偏移。
//头像 参数:图片,左偏移,上偏移,宽,高
myCanvas.rect(0, 0, 300, 600); //画矩形 相当于画布的背景色
myCanvas.setFillStyle('yellow');
myCanvas.fill(); //这句一定要加
let phone = '12456798798'; //可以使用变量
myCanvas.fillStyle = '#101010';
// 绘制文字
let fontSizea = 14;
myCanvas.font = `${fontSizea}px Arial`;
myCanvas.fillText('姓名: 木村林', 124, 58);
myCanvas.fillText(`手机: ${phone}`, 124, 76);
myCanvas.fillText('这是我的二维码名片,请惠存!', 49, 185);
//图片,可以用临时路径,本地图片,不能是网络图片 或者 base64
myCanvas.drawImage('../../static/img/auth.png', 33, 44, 65, 65);
//二维码(动态生成的小程序码,代码在后面)
myCanvas.drawImage(this.maskData, 55, 223, 183, 183);
myCanvas.fillText('长按保存图片,扫码进入小程序', 49, 490);
//开始绘画,必须调用这一步,才会把之前的一些操作实施
myCanvas.draw(true, () => {
//海报生成图片
uni.canvasToTempFilePath({
canvasId: 'mycanvas',
success: (res) => {
console.log("图片",res);
// 在H5平台下,tempFilePath 为 base64
this.imgurl = res.tempFilePath;
uni.hideLoading();
},
fail: () => {
uni.showToast({
title: '名片加载失败',
duration: 2000
});
}
});
});
},
第二:生成小程序码
这里微信后台有说明,最好是后端调用微信的API接口 直接将生成的值传给前端,因为在前端没有办法配置域名,
调试方式:打开微信开发者工具勾选不校验域名,真机上也要打开调式模式,不校验域名 不然是请求不通的。
import { base64ToSave,removeSave } from '../../utils/poster.js' //引入文件
//这部分代码只做前端测试使用,具体的还要后端生成
getData(e) {
//获取accessToken
let that = this;
const APP_ID = 'xxxxxxx'; // 小程序appid
const APP_SECRET = 'xxxxxxx'; // 小程序app_secret
let access_token = '';
uni.request({
url: "https://api.weixin.qq.com/cgi-bin/token", //固定链接,不用改
data: {
grant_type: 'client_credential',
appid: APP_ID,
secret: APP_SECRET
},
success: function(res) {
console.log('获取accessToken', res)
access_token = res.data.access_token;
// 接口B:适用于需要的码数量极多的业务场景 生成的是小程序码
that.getQrCode(access_token);
}
})
},
//动态生成二维码
getQrCode(access_token) {
var that = this;
uni.request({
url: "https://api.weixin.qq.com/wxa/getwxacode?access_token=" + access_token,//固定链接,不用改
method: 'POST',
responseType: 'arraybuffer', //设置响应类型
data: {
path: 'pages/packageMark/shopDetail?id=1479', // 必须是已经发布的小程序存在的页面(否则报错)
width: 298,
auto_color: false, // 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调
line_color: {
"r": "0",
"g": "0",
"b": "0"
} // auto_color 为 false 时生效,使用 rgb 设置颜色
},
success: function(res) {
//以图片的形式展示 这里注意 生成的东西要转换成 base64 图片格式
let base64 = "data:image/jpg;base64," + wx.arrayBufferToBase64(res.data);
base64ToSave(base64).then(res=>{
that.maskData = res;
console.log('获取二维码', that.maskData)
that.canvasImage();
})
}
})
}
poster.js 文件 主要实现:将base64图片格式转成能够被使用的临时路径 形式
//base64转本地图片,将数据存储在本地
export const base64ToSave = function (base64data,FILE_BASE_NAME='tmp_base64src') {
const fsm = uni.getFileSystemManager();
return new Promise((resolve, reject) => {
//format这个跟base64数据的开头对应
const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || [];
if (!format) {
reject(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() {
resolve(filePath);
},
fail() {
reject(new Error('ERROR_BASE64SRC_WRITE'));
},
});
});
}
// 2、制作海报,保存好生成海报后的临时地址
// 3、制作完海报后删除本地数据
export const removeSave = function (FILE_BASE_NAME='tmp_base64src',format='jpg') {
return new Promise((resolve)=>{
// 把文件删除后再写进,防止超过最大范围而无法写入
const fsm = uni.getFileSystemManager(); //文件管理器
const FILE_BASE_NAME = 'tmp_base64src';
const format = 'jpg';
const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`;
fsm.unlink({
filePath: filePath,
success(res) {
console.log('文件删除成功');
},
fail(e){
console.log('readdir文件删除失败:',e)
}
});
})
}
到这里,小程序生成包含动态生成的小程序码的海报已经实现,下面是实现如何保存到相册
第三:保存图片到相册
注意:要先打开相册权限,用户可以点击小程序右上角三个点,然后选择“设置”,打开相册即可,也可以用代码控制调起弹框 询问 用户是否同意开启 相册权限(uni.openSetting)
saveImage() {
uni.showActionSheet({
itemList: ['保存图片'],
success: (res) => {
if (res.tapIndex == 0) {
console.log("文件路径",this.imgurl);
wx.saveImageToPhotosAlbum({
filePath: this.imgurl,
success: function(res) {
console.log("成功",res);
uni.showToast({
title: "保存成功"
});
removeSave();
uni.navigateBack();
},
fail: function() {
console.log("==============",res);
uni.showToast({
title: "保存失败",
icon: "none"
});
}
});
}
},
fail: function(res) {
console.log(res.errMsg);
}
});
},
这里我写的是长按海报弹出这个框,点击保存图片即可。