1、zxing
ZXing是一个开源的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口。zxing可以实现使用手机的内置的摄像头完成条形码的扫描及解码。
2、使用工具类
public class QRCodeUtils {
private static final int IMAGE_WIDTH = 80;
private static final int IMAGE_HEIGHT = 80;
/**
* 生成二维码
* @param contents
* @param width
* @param height
* @param imgPath 生成图片路径
* @return
* @throws Exception
*/
public static boolean createQRCode(String contents, int width, int height, String destImgPath) throws Exception {
return createQRCode(contents,width,height,new FileOutputStream(destImgPath));
}
/**
* 生成二维码
* @param contents
* @param width
* @param height
* @param out 生成图片数据流
* @return
* @throws Exception
*/
public static boolean createQRCode(String contents, int width, int height, OutputStream out) throws Exception {
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.MARGIN, 1);
MultiFormatWriter writer = new MultiFormatWriter();
BitMatrix matrix = writer.encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
MatrixToImageWriter.writeToStream(matrix, "PNG", out);
return true;
}
/**
* 生成带图片的二维码
* @param contents
* @param width
* @param height
* @param logoPath
* @param destImgPath 生成二维码图片路径
* @return
* @throws Exception
*/
public static boolean createQRCodeWithOverlay(String contents, int width, int height, String logoPath, String destImgPath) throws Exception {
try {
byte[] bytes = createQRCodeWithOverlay(contents,width,height,logoPath);
OutputStream os= new FileOutputStream(destImgPath);
os.write(bytes);
os.close();
return true;
} catch (IOException e) {
return false;
} catch (WriterException e) {
return false;
}
}
/**
* 生成带图片的二维码
* @param contents
* @param width
* @param height
* @param logoPath
* @return
* @throws Exception
*/
public static byte[] createQRCodeWithOverlay(String contents, int width, int height, String logoPath) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.MARGIN, 1);
MultiFormatWriter writer = new MultiFormatWriter();
BitMatrix matrix = writer.encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
BufferedImage image = MatrixToImageWriter.toBufferedImage(matrix);
// 读取源图像
BufferedImage overlay = scale(logoPath, IMAGE_WIDTH,
IMAGE_HEIGHT, true);
int deltaWidth = width - overlay.getWidth();
int deltaHeight = height - overlay.getHeight();
BufferedImage combined = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graph = (Graphics2D) combined.getGraphics();
graph.drawImage(image, 0, 0, null);
graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));
graph.drawImage(overlay, Math.round(deltaWidth / 2), Math.round(deltaHeight / 2), null);
graph.dispose();
combined.flush();
ImageIO.write(combined, "PNG", out);
return out.toByteArray();
}
/**
* 读二维码
* @param in
* @return
* @throws Exception
*/
public static Result readQRCode(InputStream in) throws Exception {
BufferedImage image = ImageIO.read(in);
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result = new MultiFormatReader().decode(bitmap);
return result;
}
public static String readQRCodeBase64String(String base64String) throws Exception {
byte[] base64Array = Base64.decodeBase64(base64String);
BufferedImage image = ImageIO.read(new ByteArrayInputStream(base64Array));
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result = new MultiFormatReader().decode(bitmap);
return result.getText();
}
/**
* 把传入的原始图像按高度和宽度进行缩放,生成符合要求的图标
*
* @param srcImageFile
* 源文件地址
* @param height
* 目标高度
* @param width
* 目标宽度
* @param hasFiller
* 比例不对时是否需要补白:true为补白; false为不补白;
* @throws IOException
*/
public static BufferedImage scale(String srcImageFile, int height, int width, boolean hasFiller)
throws IOException {
double ratio = 0.0; // 缩放比例
File file = new File(srcImageFile);
BufferedImage srcImage = ImageIO.read(file);
Image destImage = srcImage.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH);
// 计算比例
if ((srcImage.getHeight() > height) || (srcImage.getWidth() > width)) {
if (srcImage.getHeight() > srcImage.getWidth()) {
ratio = (new Integer(height)).doubleValue() / srcImage.getHeight();
} else {
ratio = (new Integer(width)).doubleValue() / srcImage.getWidth();
}
AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);
destImage = op.filter(srcImage, null);
}
if (hasFiller) {// 补白
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphic = image.createGraphics();
graphic.setColor(Color.white);
graphic.fillRect(0, 0, width, height);
if (width == destImage.getWidth(null))
graphic.drawImage(destImage, 0, (height - destImage.getHeight(null)) / 2, destImage.getWidth(null),
destImage.getHeight(null), Color.white, null);
else
graphic.drawImage(destImage, (width - destImage.getWidth(null)) / 2, 0, destImage.getWidth(null),
destImage.getHeight(null), Color.white, null);
graphic.dispose();
destImage = image;
}
return (BufferedImage) destImage;
}
}
2. 测试使用
public class Test {
public static void main(String[] args) throws Exception {
String imgPath = "d:/as/pr3.jpg";
String contents = "https://my.oschina.net/pengchanghua";
// 普通二维码的生成与解析
QRCodeUtils.createQRCode(contents, 300, 300, imgPath);
// 带图片的二维的生成与解析
imgPath = "d:/as/pr5.jpg";
String srcPath = "d:/as/logo.jpg";
QRCodeUtils.createQRCodeWithOverlay(contents, 300, 300, srcPath, imgPath);
System.out.println("生成带图片的二维码成功");
}
}
来源:oschina
链接:https://my.oschina.net/pengchanghua/blog/3211486