眾所周知,現在生活中二維碼已經是無處不見。走在街道上,隨處可見廣告標語旁有二維碼,手機上QQ,微信加個好友都能通過二維碼的方式,我不知道是什么時候興起的二維碼浪潮,但是我知道,這在我小時候可是見不到的。小小的一個方形圖片,卻能存儲着大量的信息,是不是不可思議。當然路邊的二維碼希望大家還是不要貪小便宜,隨便掃二維碼很可能給你手機內置了病毒,導致個人信息的泄露,切記切記!
話不多說,直接上代碼。
生成帶logo的二維碼代碼:

1 package com.lsd.barcode; 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 import javax.imageio.ImageIO; 15 import com.google.zxing.BarcodeFormat; 16 import com.google.zxing.BinaryBitmap; 17 import com.google.zxing.DecodeHintType; 18 import com.google.zxing.EncodeHintType; 19 import com.google.zxing.MultiFormatReader; 20 import com.google.zxing.MultiFormatWriter; 21 import com.google.zxing.Result; 22 import com.google.zxing.common.BitMatrix; 23 import com.google.zxing.common.HybridBinarizer; 24 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; 25 26 /** 27 * 二維碼工具類 28 * 29 */ 30 public class QRCodeUtil { 31 32 private static final String CHARSET = "utf-8"; 33 private static final String FORMAT_NAME = "JPG"; 34 // 二維碼尺寸 35 private static final int QRCODE_SIZE = 300; 36 // LOGO寬度 37 private static final int WIDTH = 60; 38 // LOGO高度 39 private static final int HEIGHT = 60; 40 41 private static BufferedImage createImage(String content, String imgPath, 42 boolean needCompress) throws Exception { 43 Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>(); 44 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); 45 hints.put(EncodeHintType.CHARACTER_SET, CHARSET); 46 hints.put(EncodeHintType.MARGIN, 1); 47 BitMatrix bitMatrix = new MultiFormatWriter().encode(content, 48 BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints); 49 int width = bitMatrix.getWidth(); 50 int height = bitMatrix.getHeight(); 51 BufferedImage image = new BufferedImage(width, height, 52 BufferedImage.TYPE_INT_RGB); 53 for (int x = 0; x < width; x++) { 54 for (int y = 0; y < height; y++) { 55 image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 56 : 0xFFFFFFFF); 57 } 58 } 59 if (imgPath == null || "".equals(imgPath)) { 60 return image; 61 } 62 // 插入圖片 63 QRCodeUtil.insertImage(image, imgPath, needCompress); 64 return image; 65 } 66 67 /** 68 * 插入LOGO 69 * 70 * @param source 71 * 二維碼圖片 72 * @param imgPath 73 * LOGO圖片地址 74 * @param needCompress 75 * 是否壓縮 76 * @throws Exception 77 */ 78 private static void insertImage(BufferedImage source, String imgPath, 79 boolean needCompress) throws Exception { 80 File file = new File(imgPath); 81 if (!file.exists()) { 82 System.err.println(""+imgPath+" 該文件不存在!"); 83 return; 84 } 85 Image src = ImageIO.read(new File(imgPath)); 86 int width = src.getWidth(null); 87 int height = src.getHeight(null); 88 if (needCompress) { // 壓縮LOGO 89 if (width > WIDTH) { 90 width = WIDTH; 91 } 92 if (height > HEIGHT) { 93 height = HEIGHT; 94 } 95 Image image = src.getScaledInstance(width, height, 96 Image.SCALE_SMOOTH); 97 BufferedImage tag = new BufferedImage(width, height, 98 BufferedImage.TYPE_INT_RGB); 99 Graphics g = tag.getGraphics(); 100 g.drawImage(image, 0, 0, null); // 繪制縮小后的圖 101 g.dispose(); 102 src = image; 103 } 104 // 插入LOGO 105 Graphics2D graph = source.createGraphics(); 106 int x = (QRCODE_SIZE - width) / 2; 107 int y = (QRCODE_SIZE - height) / 2; 108 graph.drawImage(src, x, y, width, height, null); 109 Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6); 110 graph.setStroke(new BasicStroke(3f)); 111 graph.draw(shape); 112 graph.dispose(); 113 } 114 115 /** 116 * 生成二維碼(內嵌LOGO) 117 * 118 * @param content 119 * 內容 120 * @param imgPath 121 * LOGO地址 122 * @param destPath 123 * 存放目錄 124 * @param needCompress 125 * 是否壓縮LOGO 126 * @throws Exception 127 */ 128 public static void encode(String content, String imgPath, String destPath, 129 boolean needCompress) throws Exception { 130 BufferedImage image = QRCodeUtil.createImage(content, imgPath, 131 needCompress); 132 mkdirs(destPath); 133 String file = new Random().nextInt(99999999)+".jpg"; 134 ImageIO.write(image, FORMAT_NAME, new File(destPath+"/"+file)); 135 } 136 137 /** 138 * 當文件夾不存在時,mkdirs會自動創建多層目錄,區別於mkdir.(mkdir如果父目錄不存在則會拋出異常) 139 * @param destPath 存放目錄 140 */ 141 public static void mkdirs(String destPath) { 142 File file =new File(destPath); 143 //當文件夾不存在時,mkdirs會自動創建多層目錄,區別於mkdir.(mkdir如果父目錄不存在則會拋出異常) 144 if (!file.exists() && !file.isDirectory()) { 145 file.mkdirs(); 146 } 147 } 148 149 /** 150 * 生成二維碼(內嵌LOGO) 151 * 152 * @param content 153 * 內容 154 * @param imgPath 155 * LOGO地址 156 * @param destPath 157 * 存儲地址 158 * @throws Exception 159 */ 160 public static void encode(String content, String imgPath, String destPath) 161 throws Exception { 162 QRCodeUtil.encode(content, imgPath, destPath, false); 163 } 164 165 /** 166 * 生成二維碼 167 * 168 * @param content 169 * 內容 170 * @param destPath 171 * 存儲地址 172 * @param needCompress 173 * 是否壓縮LOGO 174 * @throws Exception 175 */ 176 public static void encode(String content, String destPath, 177 boolean needCompress) throws Exception { 178 QRCodeUtil.encode(content, null, destPath, needCompress); 179 } 180 181 /** 182 * 生成二維碼 183 * 184 * @param content 185 * 內容 186 * @param destPath 187 * 存儲地址 188 * @throws Exception 189 */ 190 public static void encode(String content, String destPath) throws Exception { 191 QRCodeUtil.encode(content, null, destPath, false); 192 } 193 194 /** 195 * 生成二維碼(內嵌LOGO) 196 * 197 * @param content 198 * 內容 199 * @param imgPath 200 * LOGO地址 201 * @param output 202 * 輸出流 203 * @param needCompress 204 * 是否壓縮LOGO 205 * @throws Exception 206 */ 207 public static void encode(String content, String imgPath, 208 OutputStream output, boolean needCompress) throws Exception { 209 BufferedImage image = QRCodeUtil.createImage(content, imgPath, 210 needCompress); 211 ImageIO.write(image, FORMAT_NAME, output); 212 } 213 214 /** 215 * 生成二維碼 216 * 217 * @param content 218 * 內容 219 * @param output 220 * 輸出流 221 * @throws Exception 222 */ 223 public static void encode(String content, OutputStream output) 224 throws Exception { 225 QRCodeUtil.encode(content, null, output, false); 226 } 227 228 /** 229 * 解析二維碼 230 * 231 * @param file 232 * 二維碼圖片 233 * @return 234 * @throws Exception 235 */ 236 public static String decode(File file) throws Exception { 237 BufferedImage image; 238 image = ImageIO.read(file); 239 if (image == null) { 240 return null; 241 } 242 BufferedImageLuminanceSource source = new BufferedImageLuminanceSource( 243 image); 244 BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); 245 Result result; 246 Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(); 247 hints.put(DecodeHintType.CHARACTER_SET, CHARSET); 248 result = new MultiFormatReader().decode(bitmap, hints); 249 String resultStr = result.getText(); 250 return resultStr; 251 } 252 253 /** 254 * 解析二維碼 255 * 256 * @param path 257 * 二維碼圖片地址 258 * @return 259 * @throws Exception 260 */ 261 public static String decode(String path) throws Exception { 262 return QRCodeUtil.decode(new File(path)); 263 } 264 265 public static void createCode(String text,String picturepath,String location) throws Exception { 266 QRCodeUtil.encode(text, picturepath, location, true); 267 } 268 }

package com.lsd.barcode; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import com.google.zxing.LuminanceSource; public class BufferedImageLuminanceSource extends LuminanceSource { private final BufferedImage image; private final int left; private final int top; public BufferedImageLuminanceSource(BufferedImage image) { this(image, 0, 0, image.getWidth(), image.getHeight()); } public BufferedImageLuminanceSource(BufferedImage image, int left, int top, int width, int height) { super(width, height); int sourceWidth = image.getWidth(); int sourceHeight = image.getHeight(); if (left + width > sourceWidth || top + height > sourceHeight) { throw new IllegalArgumentException( "Crop rectangle does not fit within image data."); } for (int y = top; y < top + height; y++) { for (int x = left; x < left + width; x++) { if ((image.getRGB(x, y) & 0xFF000000) == 0) { image.setRGB(x, y, 0xFFFFFFFF); // = white } } } this.image = new BufferedImage(sourceWidth, sourceHeight, BufferedImage.TYPE_BYTE_GRAY); this.image.getGraphics().drawImage(image, 0, 0, null); this.left = left; this.top = top; } public byte[] getRow(int y, byte[] row) { if (y < 0 || y >= getHeight()) { throw new IllegalArgumentException( "Requested row is outside the image: " + y); } int width = getWidth(); if (row == null || row.length < width) { row = new byte[width]; } image.getRaster().getDataElements(left, top + y, width, 1, row); return row; } public byte[] getMatrix() { int width = getWidth(); int height = getHeight(); int area = width * height; byte[] matrix = new byte[area]; image.getRaster().getDataElements(left, top, width, height, matrix); return matrix; } public boolean isCropSupported() { return true; } public LuminanceSource crop(int left, int top, int width, int height) { return new BufferedImageLuminanceSource(image, this.left + left, this.top + top, width, height); } public boolean isRotateSupported() { return true; } public LuminanceSource rotateCounterClockwise() { int sourceWidth = image.getWidth(); int sourceHeight = image.getHeight(); AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, sourceWidth); BufferedImage rotatedImage = new BufferedImage(sourceHeight, sourceWidth, BufferedImage.TYPE_BYTE_GRAY); Graphics2D g = rotatedImage.createGraphics(); g.drawImage(image, transform, null); g.dispose(); int width = getWidth(); return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth - (left + width), getHeight(), width); } }
分別保存在兩個java類文件中,然后打成jar包,直接調用包中的createCode方法即可,參數別分為二維碼內容,圖片路徑,存放地址,圖片是否需要壓縮。