微信小程序生成详情页面二维码

在获取二维码之前我们首先要获取到access_token。

1.获取access_token

官方接口:https://api.weixin.qq.com/cgi-bin/token?appid= ‘’&secret=’’ ;
appid和secret就是小程序的appid和密钥,可以在微信公众号平台上面查看自己的小程序信息。

2.生成详情页面的二维码,可以传递参数的那种

在这里我使用的官方接口:
https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=" + access_token
还需要传递两个参数二维码生成的页面,和二维码的宽度
注意这两个参数的传递格式是json格式的:

data:{
"path":"pages/index/index?query=' ' ",
"width":120
}

这两个接口在前端也可以直接使用生成二维码,但是发布在线上的小程序就不能生成二维码了,因为接口请求的不能是https://api.weixin.qq.com
这里我们需要在后端处理生成二维码接口,具体后端代码如下图所示:

    @SuppressWarnings("resource")
	@ApiOperation(value = "生成二维码", notes = "发送到前端")
	@ApiImplicitParam(name = "id", value = "id", paramType = "query", required = true, dataType = "Long")
	@RequestMapping("/getCode")
	private void getCode(@RequestParam Long id, HttpServletResponse response) throws IOException {
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		String grant_type = "client_credential";
		String appid = " "; //你的appid
		String secret = " ";  //你的密钥
		String param = "grant_type=" + grant_type + "&appid=" + appid + "&secret=" + secret;
		String ft = HttpRequest.sendGet("https://api.weixin.qq.com/cgi-bin/token", param);
		// 解析相应内容(转换成json对象)
		JSONObject json = JSON.parseObject(ft);
		// 拿到accesstoken
		String access_token = (String) json.get("access_token");
		String path = "pages/index/index?id=" + id;
		int width = 110;
		String params = "{\"path\":\"" + path + "\",\"width\":" + width + "}";
		params = JSON.parseObject(params).toJSONString();
		BufferedImage image = HttpRequest
				.postWechatImage("https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=" + access_token, params);
		ImageIO.write(image, "JPEG", response.getOutputStream());
	}

这里此接口返回给前端的直接就是二维码的图片。
postWechatImage方法的实现如下:

/**
	 * 请求微信二维码图片 返回BufferedImage
	 * 
	 * @param url   发送请求的 URL
	 * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
	 * @return BufferedImage
	 */
	public static BufferedImage postWechatImage(String url, String param) {
		PrintWriter out = null;
		InputStream inputStream = null;
		BufferedImage image = null;
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(conn.getOutputStream());
			// 发送请求参数
			out.print(param);
			// flush输出流的缓冲
			out.flush();
			inputStream = conn.getInputStream();
			image = ImageIO.read(inputStream);
		} catch (Exception e) {
			System.out.println("发送 POST 请求出现异常!" + e);
			e.printStackTrace();
		}
		// 使用finally块来关闭输出流、输入流
		finally {
			try {
				if (out != null) {
					out.close();
				}
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
		return image;
	}

2.前端实现过程:

	// 生成页面的二维码
			uni.request({
				url: "https://wx.zzsnqyjxh.org/test/app/user/getCode?id=" + that.id,
				// url: 'http://192.168.1.166:9001/test/app/user/getCode?id=' + that.id,
				method: "POST",
				success(res) {
					 that.qrcode ='https://wx.zzsnqyjxh.org/test/app/user/getCode?id='+ that.id; //这个接口就是图片地址
					 // 转化成base64为保存
					that.codeTobase64(that.qrcode);
				}
			});
		}

转化为base64是用于绘制画布,绘制画布时不能是在线图片地址
绘制画布保存二维码的代码如下:

//先对图片进行处理
// 转化二维码
				// 绘制网略图片
				var codePath = wx.env.USER_DATA_PATH + '/goods' + 'invite' + '.png'; //创建名为invite的本地文件
				var codeData = this.codetoBase64Url.replace(/^data:image\/\w+;base64,/, ""); //清除base64前缀
				var ft = wx.getFileSystemManager(); //获得文件系统管理器  用于操作临时文件 

完整的小程序保存二维码的代码如下:

//小程序端保存图片
			saveImage() {
				uni.showLoading({
					title: '图片绘制中...',
				})
				// 转化二维码
				// 绘制网略图片
				var codePath = wx.env.USER_DATA_PATH + '/goods' + 'invite' + '.png'; //创建名为invite的本地文件
				var codeData = this.codetoBase64Url.replace(/^data:image\/\w+;base64,/, ""); //清除base64前缀
				var ft = wx.getFileSystemManager(); //获得文件系统管理器  用于操作临时文件 
				const context = uni.createCanvasContext('myCanvas')
				context.setFillStyle('#FFFFFF')
				context.setFillStyle('#1E1E1E') //文字颜色:默认黑色
				context.setFontSize(16); //设置字体大小,默认10
				context.textAlign = 'center' // 设置位置
				context.font = 'normal bold 12px sans-serif'; // 字体样式
				context.fillText(this.goodsName, 100, 265, 200, 20);
				context.setFillStyle('#FF0060');
				context.fillText('抢购价:' + '¥' + this.price, 50, 290, 200, 20);
				context.drawImage("../../static/discount.png",100,270,120,24);
				context.setFillStyle('#FFFFFF');
				context.fillText("再享最高6折优惠",160, 285,132,24);
				ft.writeFileSync(codePath, codeData, "base64"); //文件路径  存入内容  编码格式 可以直接使用imgPath来进行操作
				context.drawImage(codePath, 100, 300, 106, 106); //二维码
				// 绘制网略图片
				var goodsPath = wx.env.USER_DATA_PATH + '/goods' + 'dalaba' + '.png'; //创建名为invite的本地文件
				var imgData = this.toBase64Url.replace(/^data:image\/\w+;base64,/, ""); //清除base64前缀
				var fst = wx.getFileSystemManager(); //获得文件系统管理器  用于操作临时文件 
			 fst.writeFileSync(goodsPath, imgData, "base64"); //文件路径  存入内容  编码格式 可以直接使用imgPath来进行操作
				context.drawImage(goodsPath, 20, 0, 250, 250); //图片
				//重点:这边本来保存图片是写在draw之后,但第一次保存时空白,第二次才生效,写在draw回调里面就OK了。
				context.draw(false, function() {
					uni.canvasToTempFilePath({
						canvasId: 'myCanvas',
						success: function(res) {
							uni.hideLoading()
							// console.log(res.tempFilePath)
							uni.saveImageToPhotosAlbum({
								filePath: res.tempFilePath,
								success: function(res) {
									uni.showToast({
										title: '图片已保存'
									})
								}
							})
						}
					})
				})
			},

3.将图片转化为base64为的代码如下:

urlTobase64(url) {
				 var toBase64Url;
				uni.request({
					url: url,
					method: 'GET',
					responseType: 'arraybuffer',
					success: async res => {
						let base64 = wx.arrayBufferToBase64(res.data); //把arraybuffer转成base64
						toBase64Url = 'data:image/jpeg;base64,' + base64; //不加上这串字符,在页面无法显示
					}
				});
			},
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值