二维码生产与解析
程序员文章站
2022-06-21 09:08:00
...
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.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.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; public class QRCodeUtils { private static final String CODE = "utf-8"; private static final String IMAGE_TYPE = "png"; private static final int BLACK = 0xFF000000; private static final int WHITE = 0xFFFFFFFF; private static final int LOGO_SIZE = 60; /** * 生成RQ二维码 默认生成二维码 * * @author wfhe * @param content * 内容 * @param height * 高度(px) * @param width * 高度(px) * */ public static BufferedImage getRQ(String content, Integer height, Integer width, String logoPath, boolean needCompress) { if(height == null || height < 100) { height = 200; } if(width == null || width < 50) { width = height; } try { Hashtable<EncodeHintType, Object> h = new Hashtable<EncodeHintType, Object>(); h.put(EncodeHintType.CHARACTER_SET, CODE); h.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); h.put(EncodeHintType.MARGIN, 1); BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, h); return toBufferedImage(bitMatrix, logoPath, needCompress); } catch (WriterException e) { e.printStackTrace(); } return null; } /** * 转换成图片 * * @author wfhe * @param bitMatrix * @param logoPath logo文件路径 * @param needCompress logo是否要压缩 * @return */ private static BufferedImage toBufferedImage(BitMatrix bitMatrix, String logoPath, boolean needCompress ){ int width = bitMatrix.getWidth(); int height = bitMatrix.getHeight(); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); for(int x = 0; x < width; x++) { for(int y = 0; y < height; y ++) { image.setRGB(x, y, bitMatrix.get(x, y)? BLACK : WHITE); } } if(logoPath != null && !"".equals(logoPath)) wlogo(image, logoPath, needCompress); return image; } /** * 生成一、二维码,写到文件中 * * @author wfhe * @param content 内容 * @param height 高度 * @param width 宽度 * @param filePath 文件路径 * @throws Exception */ public static void wQRFile(String content, Integer height, Integer width, String filePath, String logoPath, boolean needCompress ) throws Exception { if(filePath == null || "".equals(filePath)) throw new Exception("filePath erorr : " + filePath); File file = new File(filePath); if(file == null || file.exists() == false) { try { file.createNewFile(); } catch (Exception e) { throw new Exception("filePath create fail : " + filePath); } } BufferedImage image = getRQ(content, height, width, logoPath, needCompress); ImageIO.write(image, IMAGE_TYPE, file); } /** * @author wfhe * @param filePath 需要解析的二维码图片路径 * @return */ public static String resolve(String filePath) { try { if(filePath == null || "".equals(filePath)) throw new Exception("filePath erorr : " + filePath); File file = new File(filePath); if(file == null || file.exists() == false) throw new Exception("File Not Found : " + filePath); BufferedImage imge = ImageIO.read(file); LuminanceSource source = new BufferedImageLuminanceSource(imge); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); // 解码设置编码方式为:utf-8 Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(); hints.put(DecodeHintType.CHARACTER_SET, CODE); Result result = new MultiFormatReader().decode(bitmap, hints); return result.getText(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * @author wfhe * @param bufferedImage 图片缓存 * @param logoPath logo 图片文件的路径 * @param needCompress 是否要压缩logo */ private static void wlogo(BufferedImage bufferedImage, String logoPath, boolean needCompress) { try { File file = new File(logoPath); if (!file.exists()) { throw new Exception("File Not Found : " + logoPath); } Image logo = ImageIO.read(file); int width = logo.getWidth(null); int height = logo.getHeight(null); if(needCompress){// 压缩LOGO width = LOGO_SIZE; height = LOGO_SIZE; logo = logo.getScaledInstance(width, height, Image.SCALE_SMOOTH); BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(logo, 0, 0, null); // 绘制缩小后的图 g.dispose(); } // 插入LOGO Graphics2D grap = bufferedImage.createGraphics(); int x = (bufferedImage.getWidth() - width) >> 1; int y = (bufferedImage.getHeight() - height) >> 1; grap.drawImage(logo, x, y, width, height, null); Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6); grap.setStroke(new BasicStroke(3f)); grap.draw(shape); grap.dispose(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { String filePath = "d://1.png"; String logoPath = "d://111.jpg"; QRCodeUtils.wQRFile("http://www.baidu.com", null, null, filePath, logoPath, true); System.out.println("-----成生成功----"); String s = QRCodeUtils.resolve(filePath); System.out.println("-----解析成功----"); System.out.println(s); } }