微信小程序海报生成
850
0
0
1年前
最近微信小程序需要增加一个海报分享功能,且每个用户分享的海报获客后可以确定用户归属关系。这样就需要在小程序二维码上关联分享用户的唯一标识。具体的实现思路如下。
### 第一步 获取二维码
核心代码如下
```
public class WxMiniQrcodeRequest {
//最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,
//其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
private String scene;
private String page="pages/home/home";
//正式版为 "release",体验版为 "trial",开发版为 "develop"
private String env_version="release";
//二维码的宽度,单位 px,最小 280px,最大 1280px
//自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调,默认 false
//auto_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示
// private Object lineColor;
//是否需要透明底色,为 true 时,生成透明底色的小程序
private boolean is_hyaline;
private boolean check_path = true;
private Integer width = 430;
public boolean isIs_hyaline() {
return is_hyaline;
}
}
public String generateQrcode(String appId, Long uid) {
//获取访问token (token)String MP_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}";
WxAccessTokenResponse authToken = wxAuthTokenService.getAuthToken(appId);
WxMiniQrcodeRequest request = new WxMiniQrcodeRequest();
//设置用户唯一标识(小程序载入通过onLoad获取对应参数)
request.setScene("uid=" + uid);
request.setEnv_version(sysConfig.getEnv());
//request.set_hyaline(true); 想要透明的可以设置为true
//获取二维码 String MINI_QRCODE_URI = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={}";
byte[] wxMiniQrcode = WxApi.getWxMiniQrcode(appId, authToken.getAccess_token(), request);
//上传到七牛,得到链接
String tmpDir = Paths.get(System.getenv("java.io.tmpdir"), String.valueOf(uid)).toString();
String path = tmpDir + File.separator + uid + ".png";
File file = new File(path);
try {
FileUtils.writeByteArrayToFile(file, wxMiniQrcode);
} catch (IOException e) {
logger.error("generate qrcode fail ", e);
}
String key = qiniuUtil.upload(file, "static/qrcode/recommend");
file.delete();
return key;
}
```
### 第二步 canvas合并背景图和二维码
```
<canvas class="poster-canvas" style="left:-999rpx;top:-999rpx" :style="{width:deviceWidth+'px',height: deviceHeight+'px'}" canvas-id="poster-canvas"></canvas>
async onLoad() {
//this.images.push("");
this.deviceHeight = uni.getSystemInfoSync().windowHeight;
this.deviceWidth = uni.getSystemInfoSync().windowWidth;
this.bgPath = await UniUtil.getImageInfo("https://media-cdn.threeperson.com/static/qrcode/recommend/bg/2.jpg");
//this.headPath = await UniUtil.getImageInfo(this.user.head);
this.qrcodePath = await UniUtil.getImageInfo(Constant.cdnHost+this.user.qrcode);
}
//生成图片
async createImages() {
var that = this;
let canvasId = 'poster-canvas';
const ctx = uni.createCanvasContext(canvasId);
var bgPath = this.bgPath;
//var headPath = that.headPath;
var code = that.qrcodePath;
//LoggerUtil.info("bgpath:{}, headpath:{}, qrcodepath:{}",bgPath,headPath,this.qrcodePath);
let sizeRatio = this.deviceWidth/this.deviceHeight;
//绘制图像到画布 x y width height
ctx.drawImage(bgPath, 0, 0, this.deviceWidth, this.deviceHeight);
//绘制图像到画布
let codeHeight = (that.deviceWidth * 0.25);
let codeWidth = codeHeight;
ctx.drawImage(code, (that.deviceWidth-codeWidth)-that.deviceWidth*0.09 , that.deviceHeight-codeHeight-2,codeWidth,codeHeight)
//渲染
ctx.draw(true,async function(){
let path = await UniUtil.canvasToImage(canvasId,that.deviceWidth,that.deviceHeight);
that.images.push(path);
})
//需要把canvas转成图片后才能保存
}
```
###第三步 唤起微信小程序图片预览功能
```
//
onPreviewQrcode(e){
let selectIndex = e.currentTarget.dataset.index;
let url = this.images[selectIndex];
uni.previewImage({
current:url,
indicator:'default',
urls:[url],
success:function(){
},
fail:function(err){
}
});
}
```