JAVA 控制台输出二维码 时间: 2022-06-18 18:46 分类: JAVA 有时候在做协议开发的时候,现在很多都是扫码登录了,但是想放在`Linux`服务器上面跑,该如何显示二维码呢? 有两种解决方案: 1、将二维码保存到服务器 Web 目录,然后利用额外的`http服务器`来在远端浏览器上显示二维码。 2、直接命令行终端打印二维码。 显然,方案一,需要额外搭建一个`Http服务器`,并且每次运行程序,都需要在浏览器去打开相应地址查看二维码。 所以,将二维码直接输出到控制台还是有必要的,废话不多说,直接上代码: ```java StringBuilder sb = new StringBuilder(); for (int rows = 0; rows < bitMatrix.getHeight(); rows++) { for (int cols = 0; cols < bitMatrix.getWidth(); cols++) { boolean x = bitMatrix.get(rows, cols); if (!x) { sb.append("\033[40m \033[0m"); } else { sb.append("\033[38m \033[0m"); } } sb.append("\n"); } System.out.println(sb); ``` 可以看到,上面用到了谷歌的`zxing`jar工具包中的`BitMatrix`类。 说下为什么要用到该类以及其他一些问题。 本来,我首先想到的是将普通二维码图片进行二值化处理的同时扫描整个矩阵输出二维码,但是效果不尽人意:因为普通图片中的二维码信息,即使是黑白的,但其组成并不是由单一的像素点组成,所以,控制台直接根据宽高扫描输出会特别的大,以至于整个窗口都可能显示不完整,这还怎么用手机扫描呢? 然后想到的是将普通图片通过`JAVA`的`BufferedImage`转为`BitMatrix`,但实际上跟上面的方法效果差不了多少。 最终方案就是:为何不先利用`zxing`识别二维码中的信息,然后在将识别到的结果生成一张全新的二维码,也就是一个`BitMatrix`,尝试后,效果还是挺不错的,最后附上完整代码以及效果图: ```java public static String decode(BufferedImage image) throws NotFoundException { LuminanceSource source = new BufferedImageLuminanceSource(image); Binarizer binarizer = new HybridBinarizer(source); BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer); Hashtable qrParam = new Hashtable<>(); qrParam.put(DecodeHintType.CHARACTER_SET, Charsets.UTF_8.name()); return new MultiFormatReader().decode(binaryBitmap, qrParam).getText(); } public static void printQr(String text) { String s = "生成二维码失败"; int width = 5; //随便,足够小即可,反正最后不管设置多小,控制台输出的二维码都不会变小了 int height = 5; Hashtable qrParam = new Hashtable<>(); qrParam.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); qrParam.put(EncodeHintType.CHARACTER_SET, "utf-8"); qrParam.put(EncodeHintType.MARGIN, 1); try { BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, qrParam); s = toAscii(bitMatrix); } catch (WriterException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(s); } public static String toAscii(BitMatrix bitMatrix) { StringBuilder sb = new StringBuilder(); for (int rows = 0; rows < bitMatrix.getHeight(); rows++) { for (int cols = 0; cols < bitMatrix.getWidth(); cols++) { boolean x = bitMatrix.get(rows, cols); if (!x) { sb.append("\033[40m \033[0m"); } else { sb.append("\033[38m \033[0m"); } } sb.append("\n"); } return sb.toString(); } ``` ![微信截图_20220618184210.png](https://0o0.me/usr/uploads/2022/06/3032339868.png) 实际效果根据所用的`ssh`连接终端而定,有可能是扁的,但识别还是没有问题的,如果想更美观,自行调节`\033[40m \033[0m`中间的空格个数即可。 还有就是在`xshell`中,可能显示不了,这个时候你可以调整二维码的输出颜色,即代码中的`\033[40m`这种代码,或者直接修改`xshell`的配色方案即可。 标签: 无