最近在接H5游戏的时候发现一个问题,就是在未认证的公众号中不支持微信支付,在网上找了半天资料,只能使用二维码支付,二维码支付无非就是在页面弹出一个div上面浮现一个二维码图片。
有了这个思路,同时微信本身也可以下单后生成一个二维码链接地址。只需要把这个地址封装到二维码图片中就完成了。
一、使用jquery-qrcode生成二维码
为了图方便我使用了jquery-qrcode 在页面上直接生成二维码
jquery-qrcode有2中方式,一种是canvas,一种是table,貌似大家都说canvas要快很多,毕竟我们用的是H5,所以选择canvas。
1. 加载 jQuery 和 jquery.qrcode.js:
<script type='text/javascript' src='http://cdn.staticfile.org/jquery/2.1.1/jquery.min.js'></script>
<script type="text/javascript" src="http://cdn.staticfile.org/jquery.qrcode/1.0/jquery.qrcode.min.js"></script>
2. 创建一个用于包含 QRcode 图片的 DOM 元素,比如 div:
<div id="qrcode"></div>
3. 然后通过下面代码生成 QRcode:
jQuery('#qrcode').qrcode("微信支付地址");
4. 默认生成的二维码大小是 256×256,当然可以自定义大小:
jQuery('#qrcode').qrcode({width: 64,height: 64,text: "微信支付地址"});
但是遗憾的事情来了,微信浏览器好像识别不到这张图片是二维码。我怎么调位置都不行,度娘找半天也没找到解释,最终放弃了此方式
二、使用zxing生成二维码
zxing这个东西比较牛。谷歌的牛人写的。
1、首先加入zxing-core-3.1.0.jar
2、添加MatrixToImageWriter.java和MatrixToImageConfig.java
package net.dreams9.util; import com.google.zxing.common.BitMatrix; import javax.imageio.ImageIO; import java.io.File; import java.io.OutputStream; import java.io.IOException; import java.awt.image.BufferedImage; import java.nio.file.Path; /** * Writes a {@link BitMatrix} to {@link BufferedImage}, * file or stream. Provided here instead of core since it depends on * Java SE libraries. * * @author Sean Owen */ public final class MatrixToImageWriter { private static final MatrixToImageConfig DEFAULT_CONFIG = new MatrixToImageConfig(); private MatrixToImageWriter() {} /** * Renders a {@link BitMatrix} as an image, where "false" bits are rendered * as white, and "true" bits are rendered as black. */ public static BufferedImage toBufferedImage(BitMatrix matrix) { return toBufferedImage(matrix, DEFAULT_CONFIG); } /** * As {@link #toBufferedImage(BitMatrix)}, but allows customization of the output. */ public static BufferedImage toBufferedImage(BitMatrix matrix, MatrixToImageConfig config) { int width = matrix.getWidth(); int height = matrix.getHeight(); BufferedImage image = new BufferedImage(width, height, config.getBufferedImageColorModel()); int onColor = config.getPixelOnColor(); int offColor = config.getPixelOffColor(); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { image.setRGB(x, y, matrix.get(x, y) ? onColor : offColor); } } return image; } /** * @deprecated use {@link #writeToPath(BitMatrix, String, Path)} */ @Deprecated public static void writeToFile(BitMatrix matrix, String format, File file) throws IOException { writeToPath(matrix, format, file.toPath()); } /** * Writes a {@link BitMatrix} to a file. * * @see #toBufferedImage(BitMatrix) */ public static void writeToPath(BitMatrix matrix, String format, Path file) throws IOException { writeToPath(matrix, format, file, DEFAULT_CONFIG); } /** * @deprecated use {@link #writeToPath(BitMatrix, String, Path, MatrixToImageConfig)} */ @Deprecated public static void writeToFile(BitMatrix matrix, String format, File file, MatrixToImageConfig config) throws IOException { writeToPath(matrix, format, file.toPath(), config); } /** * As {@link #writeToFile(BitMatrix, String, File)}, but allows customization of the output. */ public static void writeToPath(BitMatrix matrix, String format, Path file, MatrixToImageConfig config) throws IOException { BufferedImage image = toBufferedImage(matrix, config); if (!ImageIO.write(image, format, file.toFile())) { throw new IOException("Could not write an image of format " + format + " to " + file); } } /** * Writes a {@link BitMatrix} to a stream. * * @see #toBufferedImage(BitMatrix) */ public static void writeToStream(BitMatrix matrix, String format, OutputStream stream) throws IOException { writeToStream(matrix, format, stream, DEFAULT_CONFIG); } /** * As {@link #writeToStream(BitMatrix, String, OutputStream)}, but allows customization of the output. */ public static void writeToStream(BitMatrix matrix, String format, OutputStream stream, MatrixToImageConfig config) throws IOException { BufferedImage image = toBufferedImage(matrix, config); if (!ImageIO.write(image, format, stream)) { throw new IOException("Could not write an image of format " + format); } } }
package net.dreams9.util; import java.awt.image.BufferedImage; public class MatrixToImageConfig { public static final int BLACK = 0xFF000000; public static final int WHITE = 0xFFFFFFFF; private final int onColor; private final int offColor; /** * Creates a default config with on color {@link #BLACK} and off color {@link #WHITE}, generating normal * black-on-white barcodes. */ public MatrixToImageConfig() { this(BLACK, WHITE); } /** * @param onColor pixel on color, specified as an ARGB value as an int * @param offColor pixel off color, specified as an ARGB value as an int */ public MatrixToImageConfig(int onColor, int offColor) { this.onColor = onColor; this.offColor = offColor; } public int getPixelOnColor() { return onColor; } public int getPixelOffColor() { return offColor; } int getBufferedImageColorModel() { // Use faster BINARY if colors match default return onColor == BLACK && offColor == WHITE ? BufferedImage.TYPE_BYTE_BINARY : BufferedImage.TYPE_INT_RGB; } }
下面是我从微信中下单后获取的code_url,我想要根据这个生成一个base64位的字符串,在页面用img标签来显示
int width = 200; int height = 200; Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>(); //内容所使用编码 hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); BitMatrix bitMatrix = new MultiFormatWriter().encode(result.getJSONObject("info").getString("code_url"), BarcodeFormat.QR_CODE, width, height, hints); BufferedImage bimg = MatrixToImageWriter.toBufferedImage(bitMatrix); // bufferImage->base64 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ImageIO.write(bimg, "jpg", outputStream); BASE64Encoder encoder = new BASE64Encoder(); String base64Img = encoder.encode(outputStream.toByteArray()); result.getJSONObject("info").put("qcode", URLEncoder.encode(base64Img,"UTF-8"));
在页面上
document.getElementById("qcode").src='data:image/jpg;base64,'+decodeURIComponent(data.qcode);
这样生成的二维码在微信浏览器上面就可以自动识别了。当然二维码旁边最好不要有其他的一些图片