微信小程序 带参二维码 纯Java实现

简介: 微信小程序 带参二维码 纯Java实现

零:前言

 

开发微信小程序中,有一个常见的需求,就是“一物一码”。

比如说,一个租房管理系统,你需要为每一个房屋,甚至每一个租客,设置一个二维码,方便核验;

比如说,一个餐厅点餐系统,你需要为每一张桌,甚至每一个座位,设置一个二维码,方便用户点餐;

比如说,一个在线社交系统,你需要为每一个用户,设置一个二维码,方便用户之间添加好友;

在实际开发的系统中,能用到二维码的项目比比皆是。

那么,我们如何去生成二维码,实现客户的需求呢?

 

一:二维码是什么?

 

常见的二维码为QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型。

二维条码/二维码是用某种特定的几何图形按一定规律在平面分布的、黑白相间的、记录数据符号信息的图形;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化点。

二维码可以这样用......

●信息获取(名片、地图、WIFI密码、资料)

●网站跳转(跳转到微博、手机网站、网站)

●广告推送(用户扫码,直接浏览商家推送的视频、音频广告)

●手机电商(用户扫码、手机直接购物下单)

●防伪溯源(用户扫码、即可查看生产地;同时后台可以获取最终消费地)

●优惠促销(用户扫码,下载电子优惠券,抽奖)

●会员管理(用户手机上获取电子会员信息、VIP服务)

●手机支付(扫描商品二维码,通过银行或第三方支付提供的手机端通道完成支付)

●账号登录(扫描二维码进行各个网站或软件的登录)

 

个人理解:

1.二维码就是一个字符串,使用QQ、微信等解码工具扫描二维码后,会扫出这个字符串;

2.如果这个字符串是一个网址,则会被解码工具的自带浏览器直接打开;

3.如果使用微信扫描,且该网址(域名)关联小程序,则会优先打开关联的小程序;


 

二:二维码如何生成?

 

2.1 :我们需要用到  core-3.3.0.jar  这样一个jar包。

2.2 : 我们需要两个工具类

QRCodeUtil

1. package ypc.zwz.util;
2. 
3. import java.awt.BasicStroke;
4. import java.awt.Graphics;
5. import java.awt.Graphics2D;
6. import java.awt.Image;
7. import java.awt.Shape;
8. import java.awt.geom.RoundRectangle2D;
9. import java.awt.image.BufferedImage;
10. import java.io.File;
11. import java.io.OutputStream;
12. import java.util.Hashtable;
13. import java.util.Random;
14. import javax.imageio.ImageIO;
15. import com.google.zxing.BarcodeFormat;
16. import com.google.zxing.BinaryBitmap;
17. import com.google.zxing.DecodeHintType;
18. import com.google.zxing.EncodeHintType;
19. import com.google.zxing.MultiFormatReader;
20. import com.google.zxing.MultiFormatWriter;
21. import com.google.zxing.Result;
22. import com.google.zxing.common.BitMatrix;
23. import com.google.zxing.common.HybridBinarizer;
24. import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
25. 
26. public class QRCodeUtil {
27.   private static final String CHARSET = "utf-8";
28.   private static final String FORMAT_NAME = "JPG";
29.   // 二维码尺寸
30.   private static final int QRCODE_SIZE = 300;
31.   // LOGO宽度
32.   private static final int WIDTH = 60;
33.   // LOGO高度
34.   private static final int HEIGHT = 60;
35. 
36. 
37.   private static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception {
38.     Hashtable hints = new Hashtable();
39.     hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
40.     hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
41.     hints.put(EncodeHintType.MARGIN, 1);
42.     BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,
43.         hints);
44.     int width = bitMatrix.getWidth();
45.     int height = bitMatrix.getHeight();
46.     BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
47.     for (int x = 0; x < width; x++) {
48.       for (int y = 0; y < height; y++) {
49.         image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
50.       }
51.     }
52.     if (imgPath == null || "".equals(imgPath)) {
53.       return image;
54.     }
55.     // 插入图片
56.     QRCodeUtil.insertImage(image, imgPath, needCompress);
57.     return image;
58.   }
59. 
60.   private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception {
61.     File file = new File(imgPath);
62.     if (!file.exists()) {
63.       System.err.println("" + imgPath + "   该文件不存在!");
64.       return;
65.     }
66.     Image src = ImageIO.read(new File(imgPath));
67.     int width = src.getWidth(null);
68.     int height = src.getHeight(null);
69.     if (needCompress) { // 压缩LOGO
70.       if (width > WIDTH) {
71.         width = WIDTH;
72.       }
73.       if (height > HEIGHT) {
74.         height = HEIGHT;
75.       }
76.       Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
77.       BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
78.       Graphics g = tag.getGraphics();
79.       g.drawImage(image, 0, 0, null); // 绘制缩小后的图
80.       g.dispose();
81.       src = image;
82.     }
83.     // 插入LOGO
84.     Graphics2D graph = source.createGraphics();
85.     int x = (QRCODE_SIZE - width) / 2;
86.     int y = (QRCODE_SIZE - height) / 2;
87.     graph.drawImage(src, x, y, width, height, null);
88.     Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
89.     graph.setStroke(new BasicStroke(3f));
90.     graph.draw(shape);
91.     graph.dispose();
92.   }
93. 
94.   /*
95.    * 生成二维码
96.    */
97.   public static void encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception {
98.     BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);
99.     mkdirs(destPath);
100.    System.out.println("++++++++++++++++++++++++++");
101.    System.out.println(destPath);//user.dir指定了当前的路径 
102.    ImageIO.write(image, FORMAT_NAME, new File(destPath));
103.  }
104. 
105.  public static BufferedImage encode(String content, String imgPath, boolean needCompress) throws Exception {
106.    BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);
107.    return image;
108.  }
109. 
110.  public static void mkdirs(String destPath) {
111.    File file = new File(destPath);
112.    // 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
113.    if (!file.exists() && !file.isDirectory()) {
114.      file.mkdirs();
115.    }
116.  }
117. 
118.  public static void encode(String content, String imgPath, String destPath) throws Exception {
119.    QRCodeUtil.encode(content, imgPath, destPath, false);
120.  }
121. 
122.  public static void encode(String content, String destPath) throws Exception {
123.    QRCodeUtil.encode(content, null, destPath, false);
124.  }
125. 
126.  public static void encode(String content, String imgPath, OutputStream output, boolean needCompress)
127.      throws Exception {
128.    BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);
129.    ImageIO.write(image, FORMAT_NAME, output);
130.  }
131. 
132.  public static void encode(String content, OutputStream output) throws Exception {
133.    QRCodeUtil.encode(content, null, output, false);
134.  }
135. 
136.  /*
137.   * 解析二维码
138.   */
139.  public static String decode(File file) throws Exception {
140.    BufferedImage image;
141.    image = ImageIO.read(file);
142.    if (image == null) {
143.      return null;
144.    }
145.    BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
146.    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
147.    Result result;
148.    Hashtable hints = new Hashtable();
149.    hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
150.    result = new MultiFormatReader().decode(bitmap, hints);
151.    String resultStr = result.getText();
152.    return resultStr;
153.  }
154. 
155.  public static String decode(String path) throws Exception {
156.    return QRCodeUtil.decode(new File(path));
157.  }
158. }

BufferedImageLuminanceSource.java

1. package ypc.zwz.util;
2. 
3. import java.awt.Graphics2D;
4. import java.awt.geom.AffineTransform;
5. import java.awt.image.BufferedImage;
6. import com.google.zxing.LuminanceSource;
7. 
8. public class BufferedImageLuminanceSource extends LuminanceSource {
9. 
10.   private final BufferedImage image;
11.   private final int left;
12.   private final int top;
13. 
14.   public BufferedImageLuminanceSource(BufferedImage image) {
15.     this(image, 0, 0, image.getWidth(), image.getHeight());
16.   }
17. 
18.   public BufferedImageLuminanceSource(BufferedImage image, int left, int top, int width, int height) {
19.     super(width, height);
20. 
21.     int sourceWidth = image.getWidth();
22.     int sourceHeight = image.getHeight();
23.     if (left + width > sourceWidth || top + height > sourceHeight) {
24.       throw new IllegalArgumentException("Crop rectangle does not fit within image data.");
25.     }
26. 
27.     for (int y = top; y < top + height; y++) {
28.       for (int x = left; x < left + width; x++) {
29.         if ((image.getRGB(x, y) & 0xFF000000) == 0) {
30.           image.setRGB(x, y, 0xFFFFFFFF); // = white
31.         }
32.       }
33.     }
34. 
35.     this.image = new BufferedImage(sourceWidth, sourceHeight, BufferedImage.TYPE_BYTE_GRAY);
36.     this.image.getGraphics().drawImage(image, 0, 0, null);
37.     this.left = left;
38.     this.top = top;
39.   }
40. 
41.   public byte[] getRow(int y, byte[] row) {
42.     if (y < 0 || y >= getHeight()) {
43.       throw new IllegalArgumentException("Requested row is outside the image: " + y);
44.     }
45.     int width = getWidth();
46.     if (row == null || row.length < width) {
47.       row = new byte[width];
48.     }
49.     image.getRaster().getDataElements(left, top + y, width, 1, row);
50.     return row;
51.   }
52. 
53.   public byte[] getMatrix() {
54.     int width = getWidth();
55.     int height = getHeight();
56.     int area = width * height;
57.     byte[] matrix = new byte[area];
58.     image.getRaster().getDataElements(left, top, width, height, matrix);
59.     return matrix;
60.   }
61. 
62.   public boolean isCropSupported() {
63.     return true;
64.   }
65. 
66.   public LuminanceSource crop(int left, int top, int width, int height) {
67.     return new BufferedImageLuminanceSource(image, this.left + left, this.top + top, width, height);
68.   }
69. 
70.   public boolean isRotateSupported() {
71.     return true;
72.   }
73. 
74.   public LuminanceSource rotateCounterClockwise() {
75.     int sourceWidth = image.getWidth();
76.     int sourceHeight = image.getHeight();
77.     AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, sourceWidth);
78.     BufferedImage rotatedImage = new BufferedImage(sourceHeight, sourceWidth, BufferedImage.TYPE_BYTE_GRAY);
79.     Graphics2D g = rotatedImage.createGraphics();
80.     g.drawImage(image, transform, null);
81.     g.dispose();
82.     int width = getWidth();
83.     return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth - (left + width), getHeight(), width);
84.   }
85. 
86. }

2.3 编写测试函数

main.java

1. package ypc.zwz.main;
2. 
3. import ypc.zwz.util.QRCodeUtil;
4. 
5. public class Main {
6. 
7.  public static void main(String[] args) {
8.    for(int id = 1; id<=1;id ++) {
9.      saveHouseTwoDimensionalCode("c:",Long.valueOf(Long.parseLong(""+id)));
10.     }
11.   }
12. 
13.   public static int saveHouseTwoDimensionalCode(String filePath,Long id){
14.     String text = "https://ypcqmm.net?id=" + id;
15.     // 二维码中心的内嵌图片
16.     String imgPath = filePath+"\\zwz\\logo.png";
17.     // 生成的二维码的路径及名称
18.     String destPath = filePath+"\\zwz\\house_"+String.valueOf(id)+".png";
19.     //生成二维码
20.     try {
21.       QRCodeUtil.encode(text, imgPath, destPath, true);
22.     } catch (Exception e) {
23.       e.printStackTrace();
24.     }
25.     return 1;
26.   }
27. }

网址(二维码内容)可以根据实际需求进行更改(String 类型的 text 变量)

内嵌图片的文件名和位置,也可以按需更改(String 类型的 imgPath 变量)

生成二维码的图片文件位置,也可以按需更改(Stringl类型的 destPath 变量)

 

2.4 运行项目,产生二维码

然后打开指定的目录,我的是C盘zwz文件夹

 

三: 如何关联到微信小程序?

 

首先,你需要:

1.请确认你的微信小程序,是不是企业、媒体、政府及其他组织类型小程序

2.请确认你有没有通过TCP备案的域名

如果没有,可以参考我的另外一篇文章:《腾讯云服务器备案全流程 40天备案的血与泪》

3.请确认该域名的绑定服务器能否可以用


如果以上三个条件都具备了,那么可以参考官网文档进行扫普通链接二维码打开小程序的配置了。

点我打开官网文档链接

 

四: 总结

总而言之,本文讲解了微信小程序中,如何生成自定义的二维码,使得用户使用微信,扫描该二维码,可以进入指定的微信小程序。


相关文章
|
8天前
|
小程序 前端开发 算法
|
1月前
|
小程序 Java
小程序访问java后台失败解决方案
小程序访问java后台失败解决方案
42 2
|
1月前
|
小程序 JavaScript Java
小程序访问java后台
小程序访问java后台
26 1
|
2月前
|
小程序 JavaScript
小程序生成二维码
小程序生成二维码
34 9
|
28天前
|
算法 小程序 Java
java制作海报三:获取微信二维码详情,并改变大小,合成到海报(另一张图片)上
这篇文章介绍了如何使用Java获取微信小程序的二维码,并将其调整大小后合成到海报(另一张图片)上。
37 0
|
1月前
|
小程序
java--微信小程序发送模板消息
java--微信小程序发送模板消息
92 0
|
1月前
|
小程序 前端开发 Java
java 生成小程序二维码
java 生成小程序二维码
14 0
|
1月前
|
小程序 Java
小程序通过get请求提交数据到java后台
小程序通过get请求提交数据到java后台
28 0
|
4月前
|
小程序 数据挖掘 UED
餐饮店小程序开发定制桌边二维码点餐系统
随着技术不断进步,各行各业都在使用新工具来提高效率和服务质量。餐饮业也不例外。餐饮点餐小程序系统是基于微信公众平台开发的在线点餐方式。顾客可以通过手机微信扫描餐桌上的二维码,进入餐厅的点餐小程序,选择菜品、数量和口味,直接完成点餐。点餐系统会自动保存并发送给厨房,避免了传统手工点餐容易出错的问题。
|
3月前
|
小程序 前端开发 Java

热门文章

最新文章