微信、支付宝小程序二码合一

发布于 — 2019 年 04 月 07 日
#小程序 #二维码

背景

随着现在小程序的流行,许多软件也将web页面转移到小程序之中。让用户更方便的使用。当我们做了微信和支付宝两个的小程序后,意味着我们要将两个二维码展示给用户扫码。所以当需要将微信、支付宝小程序二维码合一,或者对其做一些自定义操作时,就不能再使用官方提供的二维码生成接口。

微信、支付宝官方也提供了自定义二维码的文档:

微信:https://developers.weixin.qq.com/miniprogram/introduction/qrcode.html

支付宝:https://docs.alipay.com/mini/introduce/vzd5v0

所以通过上面的设置就可以实现二维码合一的操作。

原理解析

  1. 二维码存储的是一串信息,微信官网二维码里面可能存储的为:https://weixin.com?appid=123。支付宝二维码存储的可能是:https://alipay.com?appid=abc。这种有一定规则的信息。
  2. 我们通过两个的自定义设置,将访问两者小程序的二维码信息进行合一。比如,定义:https://www.abc.com,让微信和支付宝扫描到这个信息后都跳转到我们的小程序中。那就可以实现二维码合一。

代码实现

我们自定义了规则,就需要自己去生成二维码,而不能使用官方提供的接口进行生成了。

使用java生成二维码并且添加logo图片,二维码下方添加说明文字的代码。为了生成的二维码好看一些,我的logo图片使用了圆角,白色背景。

首先导入jar包

<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.3.0</version>
</dependency>
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.lang.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author LiuNaiJie
 * on 2019-04-01
 */
public class QrCodeUtils {
	/**
	 * 黑色
	 */

	private static final int QRCOLOR = 0xFF000000;
	/**
	 * 白色
	 */
	private static final int BGWHITE = 0xFFFFFFFF;
	/**
	 * 二维码宽
	 */
	private static final int WIDTH = 400;
	/**
	 * 二维码高
	 */
	private static final int HEIGHT = 400;
	/**
	 * 用于设置QR二维码参数
	 */
	private static Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>() {
		private static final long serialVersionUID = 1L;

		{
			// 设置QR二维码的纠错级别(H为最高级别)具体级别信息
			put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
			// 设置编码方式
			put(EncodeHintType.CHARACTER_SET, "utf-8");
			put(EncodeHintType.MARGIN, 0);
		}
	};

	/**
	 * @param logoFile logo图片
	 * @param codeFile 生成的二维码
	 * @param qrUrl    二维码内容
	 * @param note     二维码下方说明文字
	 */
	public static void drawLogoQRCode(File logoFile, File codeFile, String qrUrl, String note) {
		try {
			MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
			// 参数顺序分别为:二维码内容,编码类型,生成图片宽度,生成图片高度,设置参数
			BitMatrix bm = multiFormatWriter.encode(qrUrl, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
			BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
			// 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
			for (int x = 0; x < WIDTH; x++) {
				for (int y = 0; y < HEIGHT; y++) {
					image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);
				}
			}
			int width = image.getWidth();
			int height = image.getHeight();
			//添加logo图片
			if (Objects.nonNull(logoFile) && logoFile.exists()) {
				// 构建绘图对象l
				Graphics2D g = image.createGraphics();
				// 读取logo图片
				BufferedImage logo = ImageIO.read(logoFile);
				// 开始绘制logo图片 logo大小为整体的 1/4  开始绘制的x,y为3/8处。
				g.drawImage(logo, width * 3 / 8, height * 3 / 8, width / 4, height / 4, null);
				g.dispose();
				logo.flush();
			}
			// 添加下方说明文字
			if (StringUtils.isNotEmpty(note)) {
				// 新的图片,把带logo的二维码下面加上文字
				BufferedImage outImage = new BufferedImage(400, 445, BufferedImage.TYPE_4BYTE_ABGR);
				Graphics2D outg = outImage.createGraphics();
				// 画二维码到新的面板
				outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
				// 画文字到新的面板
				outg.setColor(Color.BLACK);
				// 字体、字型、字号
				outg.setFont(new Font("黑体", Font.PLAIN, 30));
				int strWidth = outg.getFontMetrics().stringWidth(note);
				// 画文字
				outg.drawString(note, 200 - strWidth / 2, height + (outImage.getHeight() - height) / 2 + 12);
				outg.dispose();
				outImage.flush();
				image = outImage;
			}
			image.flush();
			ImageIO.write(image, "png", codeFile);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

最后使用main方法进行测试

1
2
3
4
5
public static void main(String[] args) {
        File logoFile = new File("/xxx/logo.jpg");
        File codeFile = new File("/xxx/content.png");
        QrCodeUtils.drawLogoQRCode(logoFile,codeFile,"https://www.liunaijie.top","liunaijie.top");
    }

最终生成如下的二维码:

avatar