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);
}
}