二维码工具类
package util; import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Shape; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.URL; import java.util.HashMap; import java.util.Hashtable; import javax.imageio.ImageIO; import com.google.zxing.BarcodeFormat; import com.google.zxing.BinaryBitmap; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatReader; import com.google.zxing.MultiFormatWriter; import com.google.zxing.NotFoundException; import com.google.zxing.Result; import com.google.zxing.WriterException; import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.common.BitMatrix; import com.google.zxing.common.HybridBinarizer; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import net.sf.json.JSONObject; /** * @todo 二维码工具 * @author zhangyanan * @date 2018年8月6日 */ public class QRCodeUtil { private static final String CHARSET = "UTF-8"; private static final String FORMAT_NAME = "JPG"; // 二维码尺寸 private static final int QRCODE_SIZE = 200; // LOGO宽度 private static final int WIDTH = 40; // LOGO高度 private static final int HEIGHT = 40; public static void main(String[] args) throws Exception { create(); // System.out.println(decoderQRCode("D:/8.jpg")); // System.out.println(decodeBarCode("D:/8.jpg")); } private static void create() throws Exception, FileNotFoundException { String dir = "E:/QR.jpg"; String content = "微信提醒您:您的账户已被盗";// ConfigUtil.getProperty("project.url") String logoImgPath = "file:///taobao.jpg";// "http://192.168.100.2/cut.jpg"; File file = new File(dir); QRCodeUtil.encode(content, logoImgPath, new FileOutputStream(file), true); System.out.println("生成二维码成功"); } /** * @todo * @author zhangyanan * @date 2018年8月6日 * @param content * 二维码内容 * @param logoImgPath * Logo * @param needCompress * 是否压缩Logo * @return 返回二维码图片 * @throws WriterException * @throws IOException * BufferedImage TODO 创建二维码图片 */ private static BufferedImage createImage(String content, String logoImgPath, boolean needCompress) throws WriterException, IOException { Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>(); hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); hints.put(EncodeHintType.CHARACTER_SET, CHARSET); hints.put(EncodeHintType.MARGIN, 0); BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints); int width = bitMatrix.getWidth(); int height = bitMatrix.getHeight(); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); } } if (logoImgPath == null || "".equals(logoImgPath)) { return image; } // 插入图片 QRCodeUtil.insertImage(image, logoImgPath, needCompress); return image; } /** * @todo * @author zhangyanan * @date 2018年8月6日 * @param source * 二维码图片 * @param logoImgPath * Logo * @param needCompress * 是否压缩Logo * @throws IOException * void TODO 添加Logo */ private static void insertImage(BufferedImage source, String logoImgPath, boolean needCompress) throws IOException { /* * File file = new File(logoImgPath); if (!file.exists()) { return; } */ URL url = new URL(logoImgPath); Image src; try { src = ImageIO.read(url.openStream()); } catch (Exception e) { // TODO Auto-generated catch block // e.printStackTrace(); return; } // Image src = ImageIO.read(new File(logoImgPath)); int width = src.getWidth(null); int height = src.getHeight(null); if (needCompress) { // 压缩LOGO if (width > WIDTH) { width = WIDTH; } if (height > HEIGHT) { height = HEIGHT; } Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH); BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(image, 0, 0, null); // 绘制缩小后的图 g.dispose(); src = image; } // 插入LOGO Graphics2D graph = source.createGraphics(); int x = (QRCODE_SIZE - width) / 2; int y = (QRCODE_SIZE - height) / 2; graph.drawImage(src, x, y, width, height, null); Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6); graph.setStroke(new BasicStroke(3f)); graph.draw(shape); graph.dispose(); } /** * @todo * @author zhangyanan * @date 2018年8月6日 * @param content * 二维码内容 * @param logoImgPath * Logo * @param destPath * 二维码输出路径 * @param needCompress * 是否压缩Logo * @throws Exception * void TODO 生成带Logo的二维码 */ public static void encode(String content, String logoImgPath, String destPath, boolean needCompress) throws Exception { BufferedImage image = QRCodeUtil.createImage(content, logoImgPath, needCompress); FileUtils.mkdirs(destPath); ImageIO.write(image, FORMAT_NAME, new File(destPath)); } /** * @todo * @author zhangyanan * @date 2018年8月6日 * @param content * 二维码内容 * @param destPath * 二维码输出路径 * @throws Exception * void TODO 生成不带Logo的二维码 */ public static void encode(String content, String destPath) throws Exception { QRCodeUtil.encode(content, null, destPath, false); } /** * @todo * @author zhangyanan * @date 2018年8月6日 * @param content * 二维码内容 * @param logoImgPath * Logo * @param output * 输出流 * @param needCompress * 是否压缩Logo * @throws Exception * void TODO 生成带Logo的二维码,并输出到指定的输出流 */ public static void encode(String content, String logoImgPath, OutputStream output, boolean needCompress) throws Exception { BufferedImage image = QRCodeUtil.createImage(content, logoImgPath, needCompress); ImageIO.write(image, FORMAT_NAME, output); } /** * @todo * @author zhangyanan * @date 2018年8月6日 * @param content * 二维码内容 * @param output * 输出流 * @throws Exception * void TODO 生成不带Logo的二维码,并输出到指定的输出流 */ public static void encode(String content, OutputStream output) throws Exception { QRCodeUtil.encode(content, null, output, false); } /** * @todo 解析二维码 * @author zhangyanan * @date 2018年8月6日 */ @SuppressWarnings("unchecked") public static JSONObject decoderQRCode(String imgPath) { JSONObject json = new JSONObject(); try { MultiFormatReader formatReader = new MultiFormatReader(); // 二维码图片位置 File file = new File(imgPath); BufferedImage image = ImageIO.read(file); BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(image))); // 定义二维码的参数 @SuppressWarnings("rawtypes") HashMap hints = new HashMap(); // 设置编码字符集 hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); // 处理读取结果 Result result = formatReader.decode(binaryBitmap, hints); // System.out.println("解析结果:" + result.toString()); // System.out.println("二维码格式类型:" + result.getBarcodeFormat()); // System.out.println("二维码文本内容:" + result.getText()); json.put("result", true); // json.put("qrcode",result.getBarcodeFormat()); json.put("qrtext", result.getText()); json.put("msg", "解析成功"); } catch (NotFoundException e) { e.printStackTrace(); json.put("result", false); json.put("msg", "解析失败,请保证图片清晰重试"); } catch (IOException e) { e.printStackTrace(); json.put("result", false); json.put("msg", "解析失败,请保证图片清晰重试"); } return json; } }
一维码工具类,一维码@参考文章
package util; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Hashtable; import javax.imageio.ImageIO; import com.google.zxing.BarcodeFormat; import com.google.zxing.BinaryBitmap; import com.google.zxing.DecodeHintType; import com.google.zxing.EncodeHintType; import com.google.zxing.LuminanceSource; import com.google.zxing.MultiFormatReader; import com.google.zxing.MultiFormatWriter; import com.google.zxing.Result; import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.common.BitMatrix; import com.google.zxing.common.HybridBinarizer; import net.sf.json.JSONObject; /** * TODO 条形码工具类 2019年12月6日 * * @author zhangyanan */ public class BarCodeUtil { private static final int BLACK = 0xFF000000; private static final int WHITE = 0xFFFFFFFF; private static final String CHARSET = "UTF-8"; public static void main(String[] args) throws Exception { String text = "9999000026"; String result; String format = "png"; File outputFile = new File("d:" + File.separator + "rqcode.png"); outputFile = new File("d:" + File.separator + "barcode.png"); BarCodeUtil.writeToFile(BarCodeUtil.toBarCodeMatrix(text, null, null), format, outputFile); result = BarCodeUtil.decode(outputFile); System.out.println(result); } /** * TODO 将字符串编成一维条码的矩阵 2019年12月6日 * * @author zhangyanan */ public static BitMatrix toBarCodeMatrix(String str, Integer width, Integer height) { if (width == null || width < 200) { width = 200; } if (height == null || height < 50) { height = 50; } try { // 文字编码 Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>(); hints.put(EncodeHintType.CHARACTER_SET, CHARSET); BitMatrix bitMatrix = new MultiFormatWriter().encode(str, BarcodeFormat.CODE_128, width, height, hints); return bitMatrix; } catch (Exception e) { e.printStackTrace(); } return null; } /** * TODO 根据矩阵、图片格式,生成文件。 2019年12月6日 * * @author zhangyanan */ public static void writeToFile(BitMatrix matrix, String format, File file) throws IOException { BufferedImage image = toBufferedImage(matrix); if (!ImageIO.write(image, format, file)) { throw new IOException("Could not write an image of format " + format + " to " + file); } } /** * TODO 解码,需要javase包。 2019年12月6日 * * @author zhangyanan */ public static String decode(File file) { BufferedImage image; try { if (file == null || file.exists() == false) { throw new Exception(" File not found:" + file.getPath()); } image = ImageIO.read(file); LuminanceSource source = new BufferedImageLuminanceSource(image); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); Result result; // 解码设置编码方式为:utf-8, Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>(); hints.put(DecodeHintType.CHARACTER_SET, CHARSET); result = new MultiFormatReader().decode(bitmap, hints); return result.getText(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * TODO 根据点矩阵生成黑白图。 2019年12月6日 * * @author zhangyanan */ public static BufferedImage toBufferedImage(BitMatrix matrix) { int width = matrix.getWidth(); int height = matrix.getHeight(); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE); } } return image; } /** * TODO 解析条形码 2019年12月6日 * * @author zhangyanan */ public static JSONObject decodeBarCode(String imgPath) { JSONObject json = new JSONObject(); BufferedImage image = null; Result result = null; try { image = ImageIO.read(new File(imgPath)); if (image == null) { System.out.println("the decode image may be not exit."); } LuminanceSource source = new BufferedImageLuminanceSource(image); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); /* * Map<DecodeHintType, Object> hints = new Hashtable<>(); * hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE); * hints.put(DecodeHintType.CHARACTER_SET, "utf-8"); result = new * MultiFormatReader().decode(bitmap, hints); */ result = new MultiFormatReader().decode(bitmap, null); json.put("result", true); json.put("msg", "解析条形码成功"); // json.put("qrcode",result.getBarcodeFormat()); json.put("qrtext", result.getText()); System.out.println("解析结果:" + result.toString()); System.out.println("条形码格式类型:" + result.getBarcodeFormat()); System.out.println("条形码文本内容:" + result.getText()); } catch (Exception e) { e.printStackTrace(); json.put("result", false); json.put("msg", "解析失败,请保证图片清晰重试"); } return json; } }