一、概述:
1、需求:用户分享后可扫描该二维码直接进入资讯详情页。
2、微信提供的获取二维码接口:
A、https://api.weixin.qq.com/wxa/getwxacode?access_token=ACCESS_TOKEN
//通过该接口生成的小程序码,永久有效,有数量限制(100000),返回图片二进制内容
B、https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN
//通过该接口生成的小程序码,永久有效,数量暂无限制,返回图片二进制内容,调用分钟频率受限(5000次/分钟)。
C、https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=ACCESS_TOKEN
//通过该接口生成普通二维码格式的小程序码,永久有效,有数量限制,返回图片二进制内容
本文采用getwxacodeunlimit 接口来生产带参数和页面路径的小程序二维码。
二、源码:
【java】
1、获取二维码:
public String getminiqrQrBase64(String scene,String pageurl) {
//pageurl --小程序页面路径
//scene --进入到该页面所需的请求参数
InputStream inputStream = null;
OutputStream outputStream = null;
//根据APPid和密钥获取存取令牌
try {
RestTemplate rest = new RestTemplate();
String APIKEY = "微信公众平台查询";
String SECRETKEY = "微信公众平台查询";
String Tokenurl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APIKEY+"&secret="+SECRETKEY;
String requsetURL = Tokenurl.replaceAll("APIKEY",APIKEY).replaceAll("SECRETKEY",SECRETKEY);
System.err.println(requsetURL);
String jsonObject = HttpUtilShare.postToken(requsetURL,"");
JSONObject json = new JSONObject(jsonObject);
System.err.println(json);
String accessToken=json.getString("access_token");
System.err.println(accessToken);
String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken;
//定义生产二维码所需的参数、样式
Map<String, Object> param = new HashMap<>();
param.put("scene", scene);
param.put("page", pageurl);
param.put("width", 10);
param.put("auto_color", false);
param.put("is_hyaline",true);
Map<String, Object> line_color = new HashMap<>();
line_color.put("r", 0);
line_color.put("g", 0);
line_color.put("b", 0);
param.put("line_color", line_color);
System.out.println(param+"调用微信URL传参");
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
HttpEntity requestEntity = new HttpEntity(param, headers);
System.out.println("协议请求头"+headers+""+requestEntity);
ResponseEntity<byte[]> entity = rest.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
// LOG.info("调用小程序生成微信永久小程序码URL接口返回结果:" + entity.getBody());
System.out.println("返回结果"+entity.getBody()+".."+entity);
byte[] result = entity.getBody();
// LOG.info(Base64.encodeBase64String(result));
System.out.println("不知道是什么:"+Base64.encodeBase64String(result));
inputStream = new ByteArrayInputStream(result);
// 生成随机数命名图片
String filename = UUID.randomUUID().toString();
System.out.println(filename);
// 服务器存放位置
File file = new File("/home/QRCode/"+filename+".jpg");
if (!file.exists()) {
file.createNewFile();
}
outputStream = new FileOutputStream(file);
int len = 0;
byte[] buf = new byte[1024];
while ((len = inputStream.read(buf, 0, 1024)) != -1) {
outputStream.write(buf, 0, len);
}
outputStream.flush();
return getBase64(file);
} catch (Exception e) {
// LOG.error("调用小程序生成微信永久小程序码URL接口异常", e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("获取二维码");
return null;
}
2、进行编码传输
public String getBase64(File file){
String imgStr = "";
try {
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[(int) file.length()];
int offset = 0;
int numRead = 0;
while (offset < buffer.length && (numRead = fis.read(buffer, offset, buffer.length - offset)) >= 0) {
offset += numRead;
}
if (offset != buffer.length) {
throw new IOException("Could not completely read file "
+ file.getName());
}
fis.close();
BASE64Encoder encoder = new BASE64Encoder();
imgStr = encoder.encode(buffer);
} catch (Exception e) {
e.printStackTrace();
}
return imgStr;
}
【小程序端】
wx.request({
// 发送请求,获取二维码的图片流
url: '..................../shareBase64/' + scene + '/' + page,
headers: {
'Content-Type': 'application/json'
},
method: 'post',
data: {
},
success: function (result) {
console.log(result);
var data = result.data;
console.log("传过来的base64字符串"+data)
// 将二维码保存到用户手机,方便后续海报的生产
const fsm = wx.getFileSystemManager();
data = data.replace(/\ +/g, ""); //去掉空格方法
data = data.replace(/[\r\n]/g, "");
const buffer = wx.base64ToArrayBuffer(data);
const fileName = wx.env.USER_DATA_PATH + '/share_img.png'
fsm.writeFileSync(fileName, buffer, 'binary')
that.setData({
imgurl: fileName
})
console.log(that.data.imgurl)
}
})
三、扫码进入时的判断----以scene为键获取传入的页面参数
if (keys[0] == "resumeId") {
var resumeId = options.resumeId;
console.log("点击进入---"+resumeId);
this.setData({
scene: resumeId
})
}
if(keys[0] == "scene"){
console.log("扫码进入-----" + options.scene);
var resumeId = options.scene;
this.setData({
scene: resumeId
})
}
四、使用canvas绘制带有该页面二维码的海报
//将canvas转换为图片保存到本地,然后将图片路径传给image图片的src
createNewImg: function () {
var that = this;
var context = wx.createCanvasContext('mycanvas');
context.setFillStyle("#ffe200")
context.fillRect(0, 0, 375, 667)
var path = "/images/tpjy/55.jpg";
//将模板图片绘制到canvas,在开发工具中drawImage()函数有问题,不显示图片
//不知道是什么原因,手机环境能正常显示
context.drawImage(path, 0, 0, 375, 667);
var path1 = that.data.touxiang;
console.log(path1, "path1")
//将模板图片绘制到canvas,在开发工具中drawImage()函数有问题,不显示图片
var path4 = that.data.imgurl;
// context.drawImage(path2, 126, 186, 120, 120);
//不知道是什么原因,手机环境能正常显示
//绘制名字
context.setFontSize(24);
context.setFillStyle('#333333');
// context.setTextAlign('center');
// context.fillText(this.data.codeJob, 100, 100);
context.fillText("姓名:" + this.data.detail[0].name, 30, 160);
context.fillText("性别:" + this.data.codeSex, 230, 160);
context.fillText("学历:" + this.data.codeEducation, 30, 220);
context.fillText("学校:" + this.data.detail[0].gradSchool, 30, 280);
context.fillText("出生日期:" + this.data.detail[0].birth, 30, 340);
context.fillText("工作经验:" + this.data.codeWorkExcep, 30, 460);
context.fillText("地址:" + this.data.codeAddr, 30, 400);
context.stroke();
//招聘岗位居中显示
context.setFontSize(27);
context.setFillStyle('#333333');
context.setTextAlign('center');
context.fillText(this.data.codeJob, 187, 100);
context.stroke();
//绘制右下角程序码
context.drawImage(path4, 200, 500, 160, 160);
//绘制左下角扫码提示语
context.setFontSize(12);
context.setFillStyle('#333');
context.setTextAlign('left');
context.fillText("长按图片,扫码进入小程序", 35, 590);
context.fillText("查看具体信息", 35, 610);
//绘制头像
context.arc(186, 246, 50, 0, 2 * Math.PI) //画出圆
context.strokeStyle = "#ffe200";
context.clip(); //裁剪上面的圆形
// context.drawImage(path1, 136, 196, 100, 100); // 在刚刚裁剪的园上画图
context.draw();
//将生成好的图片保存到本地,需要延迟一会,绘制期间耗时
setTimeout(function () {
wx.canvasToTempFilePath({
canvasId: 'mycanvas',
success: function (res) {
var tempFilePath = res.tempFilePath;
that.setData({
imagePath: tempFilePath,
canvasHidden: true
});
},
fail: function (res) {
console.log(res);
}
});
}, 200);
},
//点击保存到相册
baocun: function () {
var that = this
wx.saveImageToPhotosAlbum({
filePath: that.data.imagePath,
success(res) {
wx.showModal({
content: '图片已保存到相册,赶紧晒一下吧~',
showCancel: false,
confirmText: '好的',
confirmColor: '#333',
success: function (res) {
if (res.confirm) {
console.log('用户点击确定');
/* 该隐藏的隐藏 */
that.setData({
maskHidden: false,
shareImg: false
})
}
},
})
},
fail: function (res) {
console.log(res);
if (res.errMsg == "saveImageToPhotosAlbum:fail cancel") {
wx.showModal({
title: '保存图片失败',
content: '您已取消保存图片到相册!',
showCancel: false
});
} else {
wx.showModal({
title: '提示',
content: '保存图片失败,您可以点击确定设置获取相册权限后再尝试保存!',
complete: function (res) {
console.log(res);
if (res.confirm) {
wx.openSetting({}) //打开小程序设置页面,可以设置权限
} else {
that.setData({
maskHidden: false,
shareImg: false
})
}
}
});
}
}
})
},
//点击生成
formSubmit: function (e) {
var that = this;
this.setData({
maskHidden: false,
actionSheetHidden: !this.data.actionSheetHidden,
shareImg: !this.data.shareImg
});
wx.showToast({
title: '生成中...',
icon: 'loading',
duration: 1000
});
setTimeout(function () {
wx.hideToast()
that.createNewImg();
that.setData({
maskHidden: true
});
}, 1000)
},