pom
<!--二维码-->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
</dependency>
<!--二维码-->
代码
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import org.apache.commons.collections.CollectionUtils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.ResultPoint;
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.multi.qrcode.QRCodeMultiReader;
import com.google.zxing.oned.Code128Writer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
public class QRCodeUtil {
public static void main(String[] args) {
replaceQrCode("D:\\new.jpg");
}
/**
* 替换原图片里面的二维码
*
* @param path 原图地址
* @throws NotFoundException 识别二维码失败
*/
public static void replaceQrCode(String path) {
try {
List<Result> rlist = new ArrayList<>();
// URL url = new URL(path);
// image = ImageIO.read(url.openStream());
BufferedImage originImage = ImageIO.read(new File(path));
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(
originImage)));
Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
// 设置编码格式
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
// 设置优化精度
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
// 设置复杂模式开启(我使用这种方式就可以识别微信的二维码了)
hints.put(DecodeHintType.PURE_BARCODE, Boolean.TYPE);
QRCodeMultiReader qc = new QRCodeMultiReader();// 一张图片有多张二维码
try {
Result[] r = qc.decodeMultiple(binaryBitmap, hints);// 解码
if (r != null && r.length > 0) {
rlist.addAll(Arrays.asList(r));
}
} catch (NotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (CollectionUtils.isNotEmpty(rlist)) {
// 替换二维码图案
Graphics2D graphics = originImage.createGraphics();
for (Result result : rlist) {
//识别出原二维码中的原链,可根据自身业务给原链进行转链或替换成新的二维码,自行参考
BufferedImage qrImage = generateQrCodeImage(result.getText());
File outputfile1 = new File("temp" + (new Date()).getTime() + ".png");
ImageIO.write(qrImage, "png", outputfile1);
// 定位点的坐标,按照左下、左上、右上顺序
ResultPoint[] resultPoint = result.getResultPoints();
float x1 = resultPoint[0].getX();
float y1 = resultPoint[0].getY();
float x2 = resultPoint[1].getX();
float y2 = resultPoint[1].getY();
// 计算二维码图片边长
double interval = (Math.sqrt(Math.abs(x1 - x2) * Math.abs(x1 - x2) + Math.abs(y1 - y2)
* Math.abs(y1 - y2)));
// 定位点与起始点的差值
double deviate = interval * 0.4 / 1.4;
double length = interval + 2 * deviate;
// 根据二维码定位坐标计算起始坐标
int x = Math.round(x2) - (int) deviate;
int y = Math.round(y2) - (int) deviate;
graphics.drawImage(qrImage, x, y, (int) length, (int) length, null);
}
originImage.flush();
graphics.dispose();
}
File outputfile = new File("ceshi.png");
ImageIO.write(originImage, "png", outputfile);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 生成无边框二维码
*
* @param content 内容
* @return 图像
*/
public static BufferedImage generateQrCodeImage(String content) {
BufferedImage bimage = null;
String format = "png";// 二维码的图片格式
HashMap<EncodeHintType, Object> hints = new HashMap<>(4);
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
hints.put(EncodeHintType.MARGIN, 0);
// 为了无边距,需设置宽度为条码自动生成规则的宽度
int width = new Code128Writer().encode(content).length;
// 二维码放大倍数
int codeMultiples = 1;
// 获取二维码内容的宽,不含两边距,当EncodeHintType.MARGIN为0时即为二维码宽度
int codeWidth = width * codeMultiples;
try {
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, codeWidth, codeWidth,
hints);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix, format, byteArrayOutputStream);
bimage = ImageIO.read(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
} catch (Exception e) {
e.printStackTrace();
}
return bimage;
}
}
参考:定位并替换原图中的二维码