java生成/解析二維碼

  1 package a;
  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 
 15 import javax.imageio.ImageIO;
 16 
 17 import com.google.zxing.BarcodeFormat;
 18 import com.google.zxing.BinaryBitmap;
 19 import com.google.zxing.DecodeHintType;
 20 import com.google.zxing.EncodeHintType;
 21 import com.google.zxing.MultiFormatReader;
 22 import com.google.zxing.MultiFormatWriter;
 23 import com.google.zxing.Result;
 24 import com.google.zxing.common.BitMatrix;
 25 import com.google.zxing.common.HybridBinarizer;
 26 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
 27 
 28 /**
 29  * 二維碼工具類
 30  * 
 31  */
 32 public class QRCodeUtil {
 33 
 34     private static final String CHARSET = "utf-8";
 35     private static final String FORMAT_NAME = "JPG";
 36     // 二維碼尺寸
 37     private static final int QRCODE_SIZE = 300;
 38     // LOGO寬度
 39     private static final int WIDTH = 60;
 40     // LOGO高度
 41     private static final int HEIGHT = 60;
 42 
 43     private static BufferedImage createImage(String content, String imgPath,
 44             boolean needCompress) throws Exception {
 45         Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
 46         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);// 設置二維碼糾錯級別
 47         hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
 48         hints.put(EncodeHintType.MARGIN, 1);// 設置兩邊空白區域
 49         // 建立比特矩陣(位矩陣)的QR碼編碼的字符串
 50         BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
 51                 BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
 52         // 使BufferedImage勾畫QRCode (getWidth()獲得的 是行二維碼像素點)
 53         int width = bitMatrix.getWidth();
 54         int height = bitMatrix.getHeight();
 55         // 開始在緩衝圖片中畫二維碼
 56         BufferedImage image = new BufferedImage(width, height,
 57                 BufferedImage.TYPE_INT_RGB);
 58         for (int x = 0; x < width; x++) {
 59             for (int y = 0; y < height; y++) {
 60                 image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000
 61                         : 0xFFFFFFFF);
 62             }
 63         }
 64         if (imgPath == null || "".equals(imgPath)) {
 65             return image;
 66         }
 67         // 插入圖片
 68         QRCodeUtil.insertImage(image, imgPath, needCompress);
 69         return image;
 70     }
 71 
 72     /**
 73      * 插入LOGO
 74      * 
 75      * @param source
 76      *            二維碼圖片
 77      * @param imgPath
 78      *            LOGO圖片地址
 79      * @param needCompress
 80      *            是否壓縮
 81      * @throws Exception
 82      */
 83     private static void insertImage(BufferedImage source, String imgPath,
 84             boolean needCompress) throws Exception {
 85         File file = new File(imgPath);
 86         if (!file.exists()) {
 87             System.err.println("" + imgPath + "   該文件不存在!");
 88             return;
 89         }
 90         Image src = ImageIO.read(new File(imgPath));
 91         int width = src.getWidth(null);
 92         int height = src.getHeight(null);
 93         if (needCompress) { // 壓縮LOGO
 94             if (width > WIDTH) {
 95                 width = WIDTH;
 96             }
 97             if (height > HEIGHT) {
 98                 height = HEIGHT;
 99             }
100             Image image = src.getScaledInstance(width, height,
101                     Image.SCALE_SMOOTH);
102             BufferedImage tag = new BufferedImage(width, height,
103                     BufferedImage.TYPE_INT_RGB);
104             Graphics g = tag.getGraphics();
105             g.drawImage(image, 0, 0, null); // 繪製縮小後的圖
106             g.dispose();
107             src = image;
108         }
109         // 插入LOGO
110         Graphics2D graph = source.createGraphics();
111         int x = (QRCODE_SIZE - width) / 2;
112         int y = (QRCODE_SIZE - height) / 2;
113         graph.drawImage(src, x, y, width, height, null);
114         Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
115         graph.setStroke(new BasicStroke(3f));
116         graph.draw(shape);
117         graph.dispose();
118     }
119 
120     /**
121      * 生成二維碼(內嵌LOGO)
122      * 
123      * @param content
124      *            內容
125      * @param imgPath
126      *            LOGO地址
127      * @param destPath
128      *            存放目錄
129      * @param needCompress
130      *            是否壓縮LOGO
131      * @throws Exception
132      */
133     public static void encode(String content, String imgPath, String destPath,
134             boolean needCompress) throws Exception {
135         BufferedImage image = QRCodeUtil.createImage(content, imgPath,
136                 needCompress);
137         mkdirs(destPath);
138         String file = new Random().nextInt(99999999) + ".jpg";
139         ImageIO.write(image, FORMAT_NAME, new File(destPath + "/" + file));
140     }
141 
142     /**
143      * 當文件夾不存在時,mkdirs會自動建立多層目錄,區別於mkdir.(mkdir若是父目錄不存在則會拋出異常)
144      * 
145      * @author
146      * @date
147      * @param destPath
148      *            存放目錄
149      */
150     public static void mkdirs(String destPath) {
151         File file = new File(destPath);
152         // 當文件夾不存在時,mkdirs會自動建立多層目錄,區別於mkdir.(mkdir若是父目錄不存在則會拋出異常)
153         if (!file.exists() && !file.isDirectory()) {
154             file.mkdirs();
155         }
156     }
157 
158     /**
159      * 生成二維碼(內嵌LOGO)
160      * 
161      * @param content
162      *            內容
163      * @param imgPath
164      *            LOGO地址
165      * @param destPath
166      *            存儲地址
167      * @throws Exception
168      */
169     public static void encode(String content, String imgPath, String destPath)
170             throws Exception {
171         QRCodeUtil.encode(content, imgPath, destPath, false);
172     }
173 
174     /**
175      * 生成二維碼
176      * 
177      * @param content
178      *            內容
179      * @param destPath
180      *            存儲地址
181      * @param needCompress
182      *            是否壓縮LOGO
183      * @throws Exception
184      */
185     public static void encode(String content, String destPath,
186             boolean needCompress) throws Exception {
187         QRCodeUtil.encode(content, null, destPath, needCompress);
188     }
189 
190     /**
191      * 生成二維碼
192      * 
193      * @param content
194      *            內容
195      * @param destPath
196      *            存儲地址
197      * @throws Exception
198      */
199     public static void encode(String content, String destPath) throws Exception {
200         QRCodeUtil.encode(content, null, destPath, false);
201     }
202 
203     /**
204      * 生成二維碼(內嵌LOGO)
205      * 
206      * @param content
207      *            內容
208      * @param imgPath
209      *            LOGO地址
210      * @param output
211      *            輸出流
212      * @param needCompress
213      *            是否壓縮LOGO
214      * @throws Exception
215      */
216     public static void encode(String content, String imgPath,
217             OutputStream output, boolean needCompress) throws Exception {
218         BufferedImage image = QRCodeUtil.createImage(content, imgPath,
219                 needCompress);
220         ImageIO.write(image, FORMAT_NAME, output);
221     }
222 
223     /**
224      * 生成二維碼
225      * 
226      * @param content
227      *            內容
228      * @param output
229      *            輸出流
230      * @throws Exception
231      */
232     public static void encode(String content, OutputStream output)
233             throws Exception {
234         QRCodeUtil.encode(content, null, output, false);
235     }
236 
237     /**
238      * 解析二維碼
239      * 
240      * @param file
241      *            二維碼圖片
242      * @return
243      * @throws Exception
244      */
245     public static String decode(File file) throws Exception {
246         BufferedImage image;
247         image = ImageIO.read(file);
248         if (image == null) {
249             return null;
250         }
251         BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(
252                 image);
253         BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
254         Result result;
255         Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
256         hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
257         result = new MultiFormatReader().decode(bitmap, hints);
258         String resultStr = result.getText();
259         return resultStr;
260     }
261 
262     /**
263      * 解析二維碼
264      * 
265      * @param path
266      *            二維碼圖片地址
267      * @return
268      * @throws Exception
269      */
270     public static String decode(String path) throws Exception {
271         return QRCodeUtil.decode(new File(path));
272     }
273 
274     public static void main(String[] args) throws Exception {
275         String text = "https://www.hao123.com/";
276         QRCodeUtil.encode(text, "G:/新建文件夾/1/2.png", "G:/新建文件夾/1/", true);
277     }
278 }
 1 package a;
 2 
 3 import java.awt.Graphics2D;
 4 import java.awt.geom.AffineTransform;
 5 import java.awt.image.BufferedImage;
 6 
 7 import com.google.zxing.LuminanceSource;
 8 /**
繼承 LuminanceSource 實現解析二維碼
*/ 9 public class BufferedImageLuminanceSource extends LuminanceSource { 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, 19 int width, int height) { 20 super(width, height); 21 22 int sourceWidth = image.getWidth(); 23 int sourceHeight = image.getHeight(); 24 if (left + width > sourceWidth || top + height > sourceHeight) { 25 throw new IllegalArgumentException( 26 "Crop rectangle does not fit within image data."); 27 } 28 29 for (int y = top; y < top + height; y++) { 30 for (int x = left; x < left + width; x++) { 31 if ((image.getRGB(x, y) & 0xFF000000) == 0) { 32 image.setRGB(x, y, 0xFFFFFFFF); // = white 33 } 34 } 35 } 36 37 this.image = new BufferedImage(sourceWidth, sourceHeight, 38 BufferedImage.TYPE_BYTE_GRAY); 39 this.image.getGraphics().drawImage(image, 0, 0, null); 40 this.left = left; 41 this.top = top; 42 } 43 44 public byte[] getRow(int y, byte[] row) { 45 if (y < 0 || y >= getHeight()) { 46 throw new IllegalArgumentException( 47 "Requested row is outside the image: " + y); 48 } 49 int width = getWidth(); 50 if (row == null || row.length < width) { 51 row = new byte[width]; 52 } 53 image.getRaster().getDataElements(left, top + y, width, 1, row); 54 return row; 55 } 56 57 public byte[] getMatrix() { 58 int width = getWidth(); 59 int height = getHeight(); 60 int area = width * height; 61 byte[] matrix = new byte[area]; 62 image.getRaster().getDataElements(left, top, width, height, matrix); 63 return matrix; 64 } 65 66 public boolean isCropSupported() { 67 return true; 68 } 69 70 public LuminanceSource crop(int left, int top, int width, int height) { 71 return new BufferedImageLuminanceSource(image, this.left + left, 72 this.top + top, width, height); 73 } 74 75 public boolean isRotateSupported() { 76 return true; 77 } 78 79 public LuminanceSource rotateCounterClockwise() { 80 int sourceWidth = image.getWidth(); 81 int sourceHeight = image.getHeight(); 82 AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 83 0.0, sourceWidth); 84 BufferedImage rotatedImage = new BufferedImage(sourceHeight, 85 sourceWidth, BufferedImage.TYPE_BYTE_GRAY); 86 Graphics2D g = rotatedImage.createGraphics(); 87 g.drawImage(image, transform, null); 88 g.dispose(); 89 int width = getWidth(); 90 return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth 91 - (left + width), getHeight(), width); 92 } 93 }
相關文章
相關標籤/搜索