#最近项目中用到二维码和条形码,一个h5端调用后端接口生成二维码或者条形码后,另一h5端扫码读取数据,实现类似数据传输的功能。
1、pom.xml依赖
<!-- 条形码 -->
<dependency>
<groupId>net.sf.barcode4j</groupId>
<artifactId>barcode4j</artifactId>
<version>2.1</version>
</dependency>
<!-- 二维码、条形码 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.4.1</version>
</dependency>
2、工具类生成二维码、条形码 BarcodeGenerator.java
import cn.hutool.core.util.RandomUtil;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.krysalis.barcode4j.HumanReadablePlacement;
import org.krysalis.barcode4j.impl.code128.Code128Bean;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
import org.krysalis.barcode4j.tools.UnitConv;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.FileSystems;
import java.nio.file.Path;
public class BarcodeGenerator {
public static void main(String[] args) throws WriterException, IOException {
String text = "{\n" +
" \"code\": 0,\n" +
" \"msg\": null,\n" +
" \"data\": {\n" +
" \"resultcode\": \"0\",\n" +
" \"resulttext\": \"调用成功\",\n" +
" \"xm\": \"张麻子\",\n" +
" \"xb\": \"1\",\n" +
" \"grbh\": \"37030303030303\",\n" +
" \"zfbz\": \"1\",\n" +
" \"zfsm\": \"\",\n" +
" \"dwmc\": \"西红市医疗保障服务中心\",\n" +
" \"ylrylb\": \"在职\",\n" +
" \"ydbz\": \"\",\n" +
" \"mzdbjbs\": \"\",\n" +
" \"mzdbbz\": \"\",\n" +
" \"sbjgbh\": \"37030101\",\n" +
" \"zhzybz\": \"0\",\n" +
" \"zhzysm\": \"\",\n" +
" \"zcyymc\": \"*\",\n" +
" \"agreement_sts\": \"S\",\n" +
" \"ye\": \"14521.67\",\n" +
" \"rqlb\": \"A\",\n" +
" \"yfdxbz\": \"\",\n" +
" \"pkrkbz\": \"\"\n" +
" }\n" +
"}";
BitMatrix matrix = new QRCodeWriter().encode(text, BarcodeFormat.QR_CODE, 800, 150);
Path file = FileSystems.getDefault().getPath(RandomUtil.randomInt(1, 1000)+"qrcode1.png");
MatrixToImageWriter.writeToPath(matrix, "PNG", file);
/** 调用 生成条形码*/
System.out.println("-------dir------->>"+System.getProperty("user.dir"));
String text2 = "37030303030303zhangxv张麻子";
// String message = new String(text2.getBytes("CP437"), "ISO-8859-1");
String message = new String(text2.getBytes("CP437"), "UTF-8");
generateFile(message, System.getProperty("user.dir") + File.separator + "barcode666.png");
}
static byte[] generateBarCode128(String msg, boolean hideText) {
if (StringUtils.isEmpty(msg)) {
return null;
}
// 如果想要其他类型的条码(CODE 39, EAN-8...)直接获取相关对象Code39Bean...等等
Code128Bean bean = new Code128Bean();
// 分辨率:值越大条码越长,分辨率越高。
final int dpi = 256;
// 设置两侧是否加空白
bean.doQuietZone(true);
// 设置条码每一条的宽度
// UnitConv 是barcode4j 提供的单位转换的实体类,用于毫米mm,像素px,英寸in,点pt之间的转换
// 设置条形码高度和宽度
bean.setBarHeight((double) ObjectUtils.defaultIfNull(10.00, 9.0D));
bean.setModuleWidth(UnitConv.in2mm(3.0f / dpi));
// 设置文本位置(包括是否显示)
if (hideText) {
bean.setMsgPosition(HumanReadablePlacement.HRP_NONE);
}
// 设置图片类型
String format = "image/png";
ByteArrayOutputStream ous = null;
byte[] imageByte = null;
try {
ous = new ByteArrayOutputStream();
BitmapCanvasProvider canvas = new BitmapCanvasProvider(ous, format, dpi,
BufferedImage.TYPE_BYTE_BINARY, false, 0);
// 生产条形码
bean.generateBarcode(canvas, msg);
// 结束
canvas.finish();
imageByte = ous.toByteArray();
} catch (IOException e) {
} finally {
try {
if (null != ous) {
ous.close();
}
} catch (Exception e) {
}
}
return imageByte;
}
public static void generateFile(String msg, String path) throws IOException {
File file = new File(path);
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file);
} catch (FileNotFoundException e) {
}
byte[] barCodeBytes = null;
barCodeBytes = generateBarCode128(msg, false);
try {
outputStream.write(barCodeBytes, 0, barCodeBytes.length);
outputStream.flush();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
if (null != outputStream) {
outputStream.close();
}
} catch (Exception e) {
}
}
}
}
3、工具类调用 BarcodeReader.java
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class BarcodeReader {
public static void main(String[] args) throws IOException, NotFoundException {
File imageFile = new File("barcode666.png");
BufferedImage bufferedImage = ImageIO.read(imageFile);
BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(bufferedImage);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
Result result = new MultiFormatReader().decode(bitmap, hints);
System.out.println("Barcode text--666>: " + result.getText());
}
}
4、工具类调用 BarcodeReader.java
import cn.hutool.core.util.RandomUtil;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author wiki
*/
public class ZxingTool {
private static final int IMAGE_WIDTH = 800;
private static final int IMAGE_HEIGHT = 150;
private static final int IMAGE_HALF_WIDTH = IMAGE_WIDTH / 2;
private static final int FRAME_WIDTH = 2;
/**
* 生成条形码
* @param contents 条形码内容
* @param width 条形码宽度
* @param height 条形码高度
* @return
*/
public static BufferedImage encodeBarcode(String contents, int width, int height){
int codeWidth = 3 + // start guard
(7 * 6) + // left bars
5 + // middle guard
(7 * 6) + // right bars
3; // end guard
codeWidth = Math.max(codeWidth, width);
BufferedImage barcode = null;
try {
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,BarcodeFormat.EAN_13, codeWidth, height, null);
barcode= MatrixToImageWriter.toBufferedImage(bitMatrix);
/**输出到图片文件 */
Path file = FileSystems.getDefault().getPath("barcode.png");
MatrixToImageWriter.writeToPath(bitMatrix, "PNG", file);
} catch (Exception e) {
e.printStackTrace();
}
return barcode;
}
/**
* 解析读取条形码
* @param barcodePath 条形码文件路径
* @return
*/
public static String decodeBarcode(String barcodePath){
BufferedImage image;
Result result = null;
try {
image = ImageIO.read(new File(barcodePath));
if (image != null) {
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
result = new MultiFormatReader().decode(bitmap, null);
}
// System.out.println("barcodetext: " + result.getText());
return result.getText();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 生成二维码
* @param context 二维码内容
* @param width 二维码图片宽度
* @param height 二维码图片高度
* @return
*/
public static BufferedImage encodeQRcode(String context,int width,int height) {
BufferedImage qrCode=null;
try {
Hashtable hints= new Hashtable();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
BitMatrix bitMatrix = new MultiFormatWriter().encode(context, BarcodeFormat.QR_CODE, width, height,hints);
qrCode = MatrixToImageWriter.toBufferedImage(bitMatrix);
/** 输出到图片文件 RandomUtil.randomInt(1, 1000)+ */
Path file = FileSystems.getDefault().getPath("qrcode.png");
MatrixToImageWriter.writeToPath(bitMatrix, "PNG", file);
} catch (Exception ex) {
Logger.getLogger(ZxingTool.class.getName()).log(Level.SEVERE, null, ex);
}
return qrCode;
}
/**
* 生成带有logo标志的二维码
* @param context 二维码存储内容
* @param width 二维码宽度
* @param height 二维码高度
* @param logoPath 二维码logo路径
* @return
*/
public static BufferedImage encodeLogoQRcode(String context,int width,int height,String logoPath) {
BufferedImage logoQRcode=null;
try {
// 读取Logo图像
BufferedImage logoImage = scale(logoPath, IMAGE_WIDTH,IMAGE_HEIGHT, true);
int[][] srcPixels = new int[IMAGE_WIDTH][IMAGE_HEIGHT];
for (int i = 0; i < logoImage.getWidth(); i++) {
for (int j = 0; j < logoImage.getHeight(); j++) {
srcPixels[i][j] = logoImage.getRGB(i, j);
}
}
Map<EncodeHintType, Object> hint = new HashMap<EncodeHintType, Object>();
hint.put(EncodeHintType.CHARACTER_SET, "utf-8");
hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
BitMatrix bitMatrix = new MultiFormatWriter().encode(context, BarcodeFormat.QR_CODE, width, height,hint);
// 二维矩阵转为一维像素数组
int halfW = bitMatrix.getWidth() / 2;
int halfH = bitMatrix.getHeight() / 2;
int[] pixels = new int[width * height];
for (int y = 0; y < bitMatrix.getHeight(); y++) {
for (int x = 0; x < bitMatrix.getWidth(); x++) {
// 读取图片
if (x > halfW - IMAGE_HALF_WIDTH
&& x < halfW + IMAGE_HALF_WIDTH
&& y > halfH - IMAGE_HALF_WIDTH
&& y < halfH + IMAGE_HALF_WIDTH) {
pixels[y * width + x] = srcPixels[x - halfW
+ IMAGE_HALF_WIDTH][y - halfH + IMAGE_HALF_WIDTH];
}
// 在图片四周形成边框
else if ((x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
&& x < halfW - IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
+ IMAGE_HALF_WIDTH + FRAME_WIDTH)
|| (x > halfW + IMAGE_HALF_WIDTH - FRAME_WIDTH
&& x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
+ IMAGE_HALF_WIDTH + FRAME_WIDTH)
|| (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
&& x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
- IMAGE_HALF_WIDTH + FRAME_WIDTH)
|| (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
&& x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH + IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
+ IMAGE_HALF_WIDTH + FRAME_WIDTH)) {
pixels[y * width + x] = 0xfffffff;
} else {
// 此处可以修改二维码的颜色,可以分别制定二维码和背景的颜色;
pixels[y * width + x] = bitMatrix.get(x, y) ? 0xff000000 : 0xfffffff;
}
}
}
logoQRcode = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
logoQRcode.getRaster().setDataElements(0, 0, width, height, pixels);
/** 输出到图片文件*/
Path file = FileSystems.getDefault().getPath(RandomUtil.randomInt(1, 1000)+"barcode.png");
MatrixToImageWriter.writeToPath(bitMatrix, "PNG", file);
} catch (Exception ex) {
Logger.getLogger(ZxingTool.class.getName()).log(Level.SEVERE, null, ex);
}
return logoQRcode;
}
/**
* 解析读取二维码
* @param qrCodePath 二维码图片路径
* @return
*/
public static String decodeQRcode(String qrCodePath){
BufferedImage image;
String qrCodeText = null;
try {
image = ImageIO.read(new File(qrCodePath));
LuminanceSource source = new BufferedImageLuminanceSource(image);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
// 对图像进行解码
Result result = new MultiFormatReader().decode(binaryBitmap, hints);
qrCodeText = result.getText();
} catch (IOException e) {
e.printStackTrace();
} catch (NotFoundException e) {
e.printStackTrace();
}
return qrCodeText;
}
/**
* 对图片进行缩放
* @param imgPath 图片路径
* @param width 图片缩放后的宽度
* @param height 图片缩放后的高度
* @param hasFiller 是否补白
* @return
*/
public static BufferedImage scale(String imgPath,int width,int height,boolean hasFiller){
double ratio = 0.0; // 缩放比例
File file = new File(imgPath);
BufferedImage srcImage = null;
try {
srcImage = ImageIO.read(file);
} catch (IOException ex) {
Logger.getLogger(ZxingTool.class.getName()).log(Level.SEVERE, null, ex);
}
Image finalImage;
finalImage = 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);
finalImage = 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 == finalImage.getWidth(null)){
graphic.drawImage(finalImage, 0,(height - finalImage.getHeight(null))/2,finalImage.getWidth(null), finalImage.getHeight(null),Color.white, null);
}else{
graphic.drawImage(finalImage,(width - finalImage.getWidth(null))/2,0,finalImage.getWidth(null), finalImage.getHeight(null),Color.white, null);
graphic.dispose();
finalImage = image;
}
}
return (BufferedImage) finalImage;
}
public static void main(String[] args) {
String contents="123456789012";
int width=800; int height=150;
encodeBarcode(contents, width, height);
String barCodePath = "H:\\workspace\\barcode.png";
String barCodeText = decodeBarcode(barCodePath);
System.out.println("barCodeText-->>"+ barCodeText);
String qrCodePath = "H:\\workspace\\qrcode.png";
encodeQRcode(contents, 200, 200);
String qrCodeText = decodeQRcode(qrCodePath);
System.out.println("qrCodeText-->> "+ qrCodeText);
}
}