微信小程序生成二维码、程序码、海报

微信小程序生成二维码、程序码、海报文章目录前言一 二维码 1 选用 getUnlimited 后端 java3 前端 小程序页面 二 普通二维码使用总结 前言微信二维码 方便传播和列表 可以用于签到扫码 分销二维码 团长二维码 分享海报等一系列二维码效果如图 一 二维码 1 选用 getUnlimited getUnlimited 因为它 永久有效 数量暂无限制 使用后端生成 返回到前端显示 2 后端 javaservice 写好的服务第一步 获取 access token 我这里把它做一个一下处理 把他存在 red


前言

微信二维码,方便传播和列表,可以用于签到扫码,分销二维码,团长二维码,分享海报等一系列二维码


一、二维码

1 选用getUnlimited

wxacode.getUnlimited
因为它:永久有效,数量暂无限制。
使用 后端生成,返回到前端显示




2 后端java

import lombok.Data; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import xyz.kszs.base.ResultInfo; import xyz.kszs.utils.RedisUtil; import javax.annotation.Resource; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.Base64; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; @Service public class WeChatService { 
      @Resource private RedisUtil redisUtil; private final String appid = "xxxxxxxxxxxxxxxxx";//小程序id private final String secret = "xxxxxxxxxxxxxxxx";//小程序秘钥 public String getAccessToken() { 
      String keyStr="Access_Token"; Object o = redisUtil.get(keyStr); if (o == null) { 
      String url = "https://api.weixin..com/cgi-bin/token?grant_type=client_credential" + "&appid=" + appid + "&secret=" + secret; RestTemplate restTemplate = new RestTemplate(); AccessToken accessToken = restTemplate.getForObject(url, AccessToken.class); if (accessToken==null){ 
      return null; }else{ 
      String token=accessToken.getAccess_token(); redisUtil.set(keyStr,token,(long)2, TimeUnit.HOURS);//存2个小时 return token; } } else { 
      return o.toString(); } } / * 获取小程序二维码 * @param scene 携带参数 * @param page 页面路径 * @return base64格式的二维码 */ public ResultInfo getQrImage(String scene,String page) { 
      //获取小程序access_token String accessToken=getAccessToken(); String result = null; // 获取小程序二维码 String url = "https://api.weixin..com/wxa/getwxacodeunlimit?access_token=" + accessToken; Map<String, Object> params = new HashMap<>(); params.put("scene", scene); params.put("page",page); params.put("check_path",false); params.put("env_version","develop"); // 注意这里byte是小写 RestTemplate restTemplate = new RestTemplate(); ResponseEntity<byte[]> responseEntity = restTemplate.postForEntity(url, params, byte[].class); // 二维码图片转base64 if (responseEntity.getStatusCode() == HttpStatus.OK) { 
      InputStream inputStream = null; ByteArrayOutputStream swapStream = null; try { 
      byte[] body = responseEntity.getBody(); inputStream = new ByteArrayInputStream(body); // 将获取流转为base64格式 byte[] data; swapStream = new ByteArrayOutputStream(); byte[] buff = new byte[1024]; int rc; while ((rc = inputStream.read(buff, 0, 1024)) > 0) { 
      swapStream.write(buff, 0, rc); } data = swapStream.toByteArray(); result = new String(Base64.getEncoder().encode(data)); result = "data:image/jpeg;base64," + result; ResultInfo resultInfo=new ResultInfo(); resultInfo.setResult(result); return resultInfo; } catch (Exception e) { 
      } finally { 
      try { 
      if (inputStream != null) { 
      inputStream.close(); } if (swapStream != null) { 
      swapStream.close(); } } catch (Exception e) { 
      } } } return null; } } @Data //获取accessToken class AccessToken { 
      private String access_token;//获取到的凭证 private Integer expires_in;//获取有效时间,单位:秒。目前是7200秒内值 private Integer errcode;//错误码 private String errmsg;//错误信息 } 

3 前端(小程序页面)

const fsm = wx.getFileSystemManager(); const FILE_BASE_NAME = 'tmp_base64src'; //自定义文件名 function base64src(base64data, cb) { 
      const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || []; if (!format) { 
      return (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() { 
      cb(filePath); }, fail() { 
      return (new Error('ERROR_BASE64SRC_WRITE')); }, }); }; module.exports = base64src; 

在js

var base64src = require('../../../utils/base64src.js'); 

生成图片方法(请求rq做一下封装,大家可以wx.request去请求你后端写好代码)

 createImg() { 
      wx.vibrateShort({ 
      type: 'light', }) wx.showLoading({ 
      title: '生成中...', }) var that = this; that.setData({ 
      isCode:true }) const query = wx.createSelectorQuery() //返回一个对象实例,通过实例可获取canvas query.select('#shareCard').fields({ 
      node: true, size: true }).exec((res) => { 
      //绘制canvas console.log('width', that.data.width) console.log('piR', that.data.pixelRatio) console.log(res) var width = res[0].width var height = res[0].height const canvas = res[0].node const ctx = canvas.getContext('2d') //使canvas适应各种屏幕不至于大小不同 let piR = that.data.pixelRatio; //比例 canvas.width = width * piR canvas.height = height * piR ctx.scale(piR, piR) // 绘制图片背景 const backImg = canvas.createImage(); let data = { 
      page: 'pages/system/login/login', scene: '108',//用户id } rq('WeChat/getQrImage', data, 'GET').then(res => { 
      base64src(res, resCurrent => { 
      console.log(resCurrent) backImg.src = resCurrent; backImg.onload = () => { 
      ctx.drawImage(backImg, width*0.1, width*0.1, width*0.8, width*0.8); wx.hideLoading(); } }) }) const avatarImg = canvas.createImage(); let avatarUrl = wx.getStorageSync('avatarUrl'); if (avatarUrl == '') avatarUrl = '/img/base/avatar.jpg' avatarImg.src = avatarUrl; //头像路径 avatarImg.onload = () => { 
      let size = width * 100 / 750; //大小 ctx.drawImage(avatarImg, width * 0.1, width-15, size, size); } //文字 ctx.font = 'normal bold 18px sans-serif'; ctx.fillStyle = '#000000'; //背景颜色 let w = width * 0.1 + 10 + width * 100 / 750; ctx.fillText('邀请你,扫码登录', w, width+10); // ctx.draw = true; }) }, 

wxml写一个页面(页面样式这里不展示呢)

 <!--遮罩--> <view class="cu-modal show"></view> <view class="modalDlg" style="--width:{ 
     {width*0.8}}px;--height:{ 
     {width*0.9}}px"> <!--关闭按钮--> <view style="text-align: center;margin-top: -100rpx;"> <icon type="cancel" size="40" color="#fff" bindtap="close"></icon> </view> <!--显示图片用的标签--> <canvas type="2d" id="shareCard" style="width: { 
     {width*0.8}}px;height: { 
     {width*0.9}}px;"></canvas> <!--创建一个画布,将它移出屏幕外看不到的地方 不看见的--> <canvas canvas-id="myQrcode" style="background:#fff;width: { 
     {width}}px;height: { 
     {width}}px; display:block; left:-800rpx;position:absolute;" /> </view> <!--按钮--> <view style="position: absolute;z-index: 9999;top: { 
     {height*4/5}}px;left:50%;margin-left: -250rpx;"> <button class="cu-btn round bg-green lg" style="width: 500rpx;" bindtap="share"> <text class="cuIcon-wechat text-lg margin-right-xs"></text> 转发与下载 </button> </view> 

二、普通二维码使用

把下来,把 weapp-qrcode.js存在你小程序中

在这里插入图片描述
在这里插入图片描述
js 引入:




import QRCode from '../../../utils/weapp-qrcode.js'; 
 new QRCode('myQrcode', { text: 'abc 12345', width: that.data.width, //canvas 画布的宽 height:that.data.width, //canvas 画布的高 padding: 0, // 生成二维码四周自动留边宽度,不传入默认为0 correctLevel: QRCode.CorrectLevel.L, // 二维码可辨识度 callback: (res) => { //工具回调数据 // 接下来就可以直接调用微信小程序的api保存到本地或者将这张二维码直接画在海报上面去,看各自需求 wx.hideLoading() console.log("生成二维码", res) backImg.src=res.path; backImg.onload = () => { ctx.drawImage(backImg, width*0.1, width*0.1, width*0.8, width*0.8); } } }) 
 <!--创建一个画布,将它移出屏幕外看不到的地方 不看见的--> <canvas canvas-id="myQrcode" style="background:#fff;width: { 
     {width}}px;height: { 
     {width}}px; display:block; left:-800rpx;position:absolute;" /> 

总结:

对于这2中生成二维码方式。我还是推荐是使用第一种的,因为比较适合小程序。第2种,可以弄来看一下。大家觉得呢

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/216812.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 上午11:00
下一篇 2026年3月18日 上午11:00


相关推荐

  • mysql乐观锁实现

    mysql乐观锁实现各锁的概念 悲观锁 假定会发生并发冲突 屏蔽一切可能违反数据完整性的操作悲观锁 从字面理解就是很悲观 每次去拿数据的时候都认为别人会修改 所以在每次拿的时候对数据上锁 这样就保证了数据的准确性 比如 mysql 中的表锁 行锁 表锁 当你对一张表进行修改时 会锁死整张表 其他的请求需要在修改完成释放锁才能继续 在高并发的情景下不适用 行锁 当你对一张表的某一行数据修改时 会锁死这一行数

    2026年3月26日
    2
  • logback-spring.xml配置文件(最佳实践)

    logback-spring.xml配置文件(最佳实践)logback-spring.xml配置文件&amp;amp;amp;lt;?xmlversion=&amp;amp;quot;1.0&amp;amp;quot;encoding=&amp;amp;quot;UTF-8&amp;amp;quot;?&amp;amp;amp;gt;&amp;amp;amp;lt;!–日志级别从低到高分为TRACE&amp;amp;amp;lt;DEBUG&amp;amp;amp;l

    2025年6月30日
    6
  • 大数据开发工程师面试题以及答案整理(二)

    大数据开发工程师面试题以及答案整理(二)Redis性能优化,单机增加CPU核数是否会提高性能1、根据业务需要选择合适的数据类型,并为不同的应用场景设置相应的紧凑存储参数。2、当业务场景不需要数据持久化时,关闭所有的持久化方式可以获得最佳的性能以及最大的内存使用量。3、如果需要使用持久化,根据是否可以容忍重启丢失部分数据在快照方式与语句追加方式之间选择其一,不要使用虚拟内存以及diskstore方式。4、不要让你的Redis所在机…

    2022年5月30日
    36
  • 完整教程:【AI编程实战】零基础用ChatGPT+Cursor开发完整Web应用:30分钟从idea到上线

    完整教程:【AI编程实战】零基础用ChatGPT+Cursor开发完整Web应用:30分钟从idea到上线

    2026年3月16日
    2
  • python升级到3.7版本安装pyaudio

    python升级到3.7版本安装pyaudio在 python 升级到 3 7 版本后 原来好用的 pyaudio 无法使用 pipinstallpy 安装也无效 官网上暂时没有 3 7 的安装版 whl 经测试 https github com intxcc pyaudio portaudio 文件下载后 按说明进行安装 win10 MicrosoftVis 2017 编译 使用静态链接库 在命令行使用命令 py

    2026年3月17日
    2
  • 几款连接redis的客户端(GUI客户端),下面记录了我使用的几款

    几款连接redis的客户端(GUI客户端),下面记录了我使用的几款几款连接redis的客户端(GUI客户端),下面记录了我使用的几款一、Redis客户端1、命令行工具命令行(建议使用,简单)比如windows的cmd和Linux、Mac的Terminal,虽然最简单好用。必须保证有redis-cli命令(windows是redis-cli.exe),比如通过安装redis就会有这个命令。2、桌面客户端RediNav(windows桌面客户端,MacOS客户端,根本不能用)评价:垃圾,完全不能用,无论win还是mac平台!我写在

    2026年1月22日
    9

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号