需要引入的依赖
<!-- https://mvnrepository.com/artifact/com.google.zxing/javase -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.2.1</version>
</dependency>
package com.fchen.qrcode;
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.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class QRCode {
/**
* 生成矩阵
* @param content
* @param width
* @param height
* @return
*/
public static BitMatrix generateQRCodeStream(String content,int width,int height){
Map<EncodeHintType,Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET,"UTF-8"); //字符编码
hints.put(EncodeHintType.MARGIN,0); //二维码与图片边距
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q); //容错等级 L、M、Q、H 其中 L 为最低, H 为最高,等级越高存储信息越少
BitMatrix bitMatrix;
try {
//参数顺序分别为:编码内容,编码类型,生成图片的宽度,生成图片的高度,设置参数
//高度和宽度都是以像素为单位
//一般content都是url,扫描后可以自动跳转到指定的地址
bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE,width,height,hints);
} catch (WriterException e) {
e.printStackTrace();
return null;
}
return bitMatrix;
}
public static void generateQRCodeImage(String content, int size){
try {
BitMatrix bitMatrix = generateQRCodeStream(content,size,size);
File file = new File("/home/ttx/app/test.jpg");
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
MatrixToImageWriter.writeToFile(bitMatrix,"jpg",file);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void decodeImage(String filePath) {
BufferedImage image;
try {
image = ImageIO.read(new File(filePath));
LuminanceSource source = new BufferedImageLuminanceSource(image);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
Result result = new MultiFormatReader().decode(binaryBitmap, hints);// 对图像进行解码
String content = result.getText();
System.out.println("图片中内容: ");
System.out.println("content: " + content);
} catch (IOException e) {
e.printStackTrace();
} catch (NotFoundException e) {
e.printStackTrace();
}
}
public static void main(String [] args){
//generateQRCodeImage("http://www.baidu.com",300);
decodeImage("C:/home/ttx/app/test.jpg");
}
}
//去白边
static BitMatrix deleteWhiteBorder(BitMatrix bitMatrix){
int [] rec = bitMatrix.getEnclosingRectangle()
int resWidth = rec[2] + 1
int resHeight = rec[3] + 1
BitMatrix resMatrix = new BitMatrix(resWidth,resHeight)
resMatrix.clear()
for(int i = 0;i < resWidth; i ++){
for(int j = 0;j < resHeight;j ++){
if(bitMatrix.get(i + rec[0], j + rec[1])){
resMatrix.set(i,j)
}
}
}
return resMatrix
}
OutputStream os
ImageOutputStream ios
ImageWriter writer
try {
//createQRCode来自上面的二维码生成
BitMatrix bitMatrix = createQRCode(data, size, size);
File file = new File(filePath)
if(!file.getParentFile().exists()){
boolean result = file.getParentFile().mkdirs()
if(!result){
println("\n\n---------------------------路径创建失败------------------------\n")
throw new RuntimeException("路径创建失败")
}else {
file.setReadable(true,false)
file.setWritable(true,false)
}
}
//原始图片流
BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix)
//要压缩的图片流
// 指定写图片的方式为 pickForm可以是jpg
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(picForm)
if(!writers.hasNext()){
throw new IllegalStateException("No writers found")
}
writer = (ImageWriter)writers.next()
os = new FileOutputStream(file)
ios = ImageIO.createImageOutputStream(os)
writer.reset()
writer.setOutput(ios)
ImageWriteParam param = new JPEGImageWriteParam(null)
// 要使用压缩,必须指定压缩方式为MODE_EXPLICIT
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT)
// 这里指定压缩的程度,参数qality是取值0~1范围内,值越小压缩的越厉害,同时图片的质量越低
param.setCompressionQuality(compressQuality)
param.setProgressiveMode(param.MODE_DISABLED)
// ColorModel.getRGBdefault() 指定压缩时使用的色彩模式
ColorModel colorModel = bufferedImage.getColorModel()
param.setDestinationType(new ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(16, 16)));
writer.write(null,new IIOImage(bufferedImage,null,null),param)
} catch (Exception e){
throw e
}finally {
if(os) {
os.flush()
os.close()
}
if(ios) {
ios.flush()
ios.close()
}
if(writer) writer.dispose()
}