【小程序码 - 设计篇】菊花绽放

本文详细介绍了微信小程序码的设计理念和技术细节,包括其选择放射状设计的原因、码的构成、生成过程,以及可扩展性。小程序码不仅具有高识别度和容错性,而且在安全性上优于传统二维码,因为其协议完全私有,仅微信支持生成和解码。

作者:lincolnlin,endyxu,changoran

2017 年四月,微信正式推出了小程序码。小程序码的使命及诞生的过程, 扫码背后藏了什么秘密?小程序码又为何长得像菊花? | 你问鹅答 一文已经作过一番介绍。本文将为你剖析更多关于小程序码的技术细节。

小程序码的前世

初见小程序码,犹如一朵盛开的菊花。

其实这种脑洞大开的异形码并非微信首创,Facebook、kik、snapchat 等公司都研发了自己体系的码。

从设计的图形上,我们把上述方案简单分成:

• 平面类 如 qrcode ,snapchart code

### 小程序菊花码实现方式及使用教程 小程序菊花码是一种带有用户自定义图片(如头像)的二维码,主要用于增强用户体验。其实现方式包括前端和后端两部分:前端负责上传用户头像并生成二维码展示,后端负责调用微信接口生成二维码并将用户上传的图片嵌入二维码中心。 #### 1. 后端实现 后端主要通过微信提供的 `wxacode.getUnlimited` 接口生成小程序码,并结合 Java 实现将用户上传的图片嵌入二维码中心的功能。 - **获取 Access Token** 微信小程序需要通过 `auth.getAccessToken` 接口获取 Access Token,这是调用其他接口的前提条件。以下是获取 Access Token 的代码示例: ```java import cn.hutool.http.HttpRequest; public static String getAccessToken(String appid, String secret) { String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret; String response = HttpRequest.get(url).execute().body(); return response; } ``` 该方法返回 JSON 格式的 Access Token 数据[^2]。 - **生成小程序码** 使用 `wxacode.getUnlimited` 接口生成小程序码,支持传入场景参数和文件路径等配置项。以下是一个生成小程序码的代码示例: ```java import cn.hutool.core.io.FileUtil; import cn.hutool.http.HttpRequest; public static void createQrCode(String accessToken, String scene, String filePath) { String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken; String json = "{\"scene\":\"" + scene + "\",\"page\":\"pages/index/index\",\"width\":430}"; byte[] bytes = HttpRequest.post(url) .body(json) .execute() .bodyBytes(); FileUtil.writeBytes(bytes, filePath); } ``` 生成的小程序码会保存到指定路径中[^2]。 - **嵌入用户头像** 将用户上传的头像嵌入到生成的小程序码中心位置,需要使用图像处理库(如 Java 的 BufferedImage)。以下是一个简单的实现示例: ```java import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; public static void embedImage(String qrCodePath, String avatarPath, String outputPath) throws Exception { BufferedImage qrCode = ImageIO.read(new File(qrCodePath)); BufferedImage avatar = ImageIO.read(new File(avatarPath)); int avatarSize = 100; // 设置头像大小 BufferedImage outputImage = new BufferedImage(qrCode.getWidth(), qrCode.getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = outputImage.createGraphics(); g2d.drawImage(qrCode, 0, 0, null); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f)); g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2d.drawImage(avatar, (qrCode.getWidth() - avatarSize) / 2, (qrCode.getHeight() - avatarSize) / 2, avatarSize, avatarSize, null); g2d.dispose(); ImageIO.write(outputImage, "png", new File(outputPath)); } ``` 该方法会将用户头像嵌入到二维码中心位置[^1]。 #### 2. 前端实现 前端主要负责用户头像上传和展示生成的二维码- **用户头像上传** 使用微信小程序的 `wx.chooseImage` 和 `wx.uploadFile` API 完成用户头像的上传。 ```javascript wx.chooseImage({ count: 1, success(res) { const tempFilePaths = res.tempFilePaths; wx.uploadFile({ url: 'https://example.com/upload', // 替换为后端上传接口地址 filePath: tempFilePaths[0], name: 'file', success(uploadRes) { console.log('上传成功', uploadRes); } }); } }); ``` - **展示生成的二维码** 用户上传头像后,前端向后端请求生成的二维码图片,并将其展示在页面上。 ```javascript wx.request({ url: 'https://example.com/generate-qrcode', // 替换为后端生成二维码接口地址 method: 'POST', data: { scene: 'user_id_123' }, success(res) { const qrcodeUrl = res.data.qrcodeUrl; this.setData({ qrcodeImageUrl: qrcodeUrl }); } }); ``` #### 3. 错误处理 在调用微信接口时,可能会遇到错误信息(如小程序未发布或页面路径不存在)。需要对返回数据进行校验,确保返回的是图片二进制数据而非 JSON 错误信息[^3]。 ```java if (!response.startsWith("{")) { // 正常返回图片二进制数据 } else { // 返回 JSON 错误信息,需要解析并提示用户 } ``` --- ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值