Barcode import com.google.zxing.*;import com.google.zxing.client.j2se.BufferedImageLuminanceSource;import com.google.zxing.client.j2se.MatrixToImageConfig;import com.google.zxing.client.j2se.MatrixToImageWriter;import com.google.zxing.commo
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageConfig;
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.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class Barcode {
private static final MultiFormatWriter WRITER;
static {
WRITER = new MultiFormatWriter();
}
private Builder builder;
public Barcode(Builder builder) {
this.builder = builder;
}
/**
* 生成BufferedImage
*
* @return BufferedImage
* @throws WriterException
*/
private BufferedImage generateOrigin() throws WriterException {
BitMatrix matrix = WRITER.encode(builder.content, builder.format, builder.width, builder.height, builder.hints);
if (Objects.nonNull(builder.matrixToImageConfig)) {
return MatrixToImageWriter.toBufferedImage(matrix, builder.matrixToImageConfig);
}
return MatrixToImageWriter.toBufferedImage(matrix);
}
/**
* 生成BufferedImage
*
* @param logo 要嵌入的logo
* @return BufferedImage
* @throws WriterException
*/
private BufferedImage generateWithLogo(BufferedImage logo) throws WriterException {
BufferedImage qrcode = generateOrigin();
BufferedImage result = new BufferedImage(qrcode.getWidth(), qrcode.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = result.createGraphics();
g2d.drawImage(qrcode, 0, 0, null);
qrcode.flush();
//抗锯齿
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//设置logo的大小,最多20%
int widthLogo = logo.getWidth(null) > result.getWidth() * 2 / 10 ?
(result.getWidth() * 2 / 10) : logo.getWidth(null);
int heightLogo = logo.getHeight(null) > result.getHeight() * 2 / 10 ?
(result.getHeight() * 2 / 10) : logo.getHeight(null);
// 计算图片放置位置,默认在中间
int x = (result.getWidth() - widthLogo) / 2;
int y = (result.getHeight() - heightLogo) / 2;
// 开始绘制图片
g2d.drawImage(logo, x, y, widthLogo, heightLogo, null);
logo.flush();
g2d.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
g2d.dispose();
result.flush();
return result;
}
/**
* 是否为二维码并且嵌入logo
* @return 是-true , 否-false
*/
private boolean isQRCodeWithLogo(){
return BarcodeFormat.QR_CODE==builder.format&&Objects.nonNull(builder.logo);
}
/**
* 生成BufferedImage
*
* @return BufferedImage
* @throws WriterException
*/
public BufferedImage generate() throws WriterException {
if (isQRCodeWithLogo()) {
return generateWithLogo(builder.logo);
} else {
return generateOrigin();
}
}
/**
* 生成指定类型图片并输出至指定输出流
*
* @param format 图片类型
* @param stream 输出流
* @throws IOException
* @throws WriterException
*/
public void generate(String format, OutputStream stream) throws IOException, WriterException {
if (isQRCodeWithLogo()) {
ImageIO.write(generateWithLogo(builder.logo), format, stream);
} else {
BitMatrix matrix = WRITER.encode(builder.content, builder.format, builder.width, builder.height, builder.hints);
if (Objects.nonNull(builder.matrixToImageConfig)) {
MatrixToImageWriter.writeToStream(matrix, format, stream, builder.matrixToImageConfig);
} else {
MatrixToImageWriter.writeToStream(matrix, format, stream);
}
}
}
/**
* 生成指定类型图片的字节数组
*
* @param format 图片类型
* @return 图片字节数组
* @throws IOException
* @throws WriterException
*/
public byte[] generate(String format) throws IOException, WriterException {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
generate(format, stream);
return stream.toByteArray();
}
/**
* 生成指定类型图片并输出至指定文件
*
* @param format 图片类型
* @param file 文件路径
* @throws IOException
* @throws WriterException
*/
public void generate(String format, File file) throws IOException, WriterException {
generate(format, new FileOutputStream(file));
}
/**
* 生成指定类型图片并输出至指定文件
*
* @param format 图片类型
* @param path 文件路径
* @throws IOException
* @throws WriterException
*/
public void generate(String format, Path path) throws IOException, WriterException {
generate(format, path.toFile());
}
public static Builder of() {
return new Builder();
}
public static Decoder from(BufferedImage image) {
return new Decoder(image);
}
public static Decoder from(InputStream stream) throws IOException {
return new Decoder(ImageIO.read(stream));
}
public static Decoder from(File file) throws IOException {
return new Decoder(ImageIO.read(file));
}
public static Decoder from(URL url) throws IOException {
return new Decoder(ImageIO.read(url));
}
public static Decoder from(byte[] bytes) throws IOException {
return new Decoder(ImageIO.read(new ByteArrayInputStream(bytes)));
}
public static Decoder from(Path path) throws IOException {
return new Decoder(ImageIO.read(path.toFile()));
}
public static class Decoder {
private static final MultiFormatReader READER;
static {
READER = new MultiFormatReader();
}
private BufferedImage bufferedImage;
private Decoder(BufferedImage bufferedImage) {
this.bufferedImage = bufferedImage;
}
public Result decode() throws NotFoundException {
BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(bufferedImage);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
Result result = READER.decode(binaryBitmap);
READER.reset();
return result;
}
}
public static class Builder {
private static final String DEFAULT_CHARACTER_SET = "utf-8";
private static final int DEFAULT_WIDTH = 200;
private static final int DEFAULT_HEIGHT = 200;
private int width = DEFAULT_WIDTH;
private int height = DEFAULT_HEIGHT;
private String content;
private BarcodeFormat format;
private Map
hints;
private BufferedImage logo;
private MatrixToImageConfig matrixToImageConfig;
private Builder() {
initDefaultHints();
}
private void initDefaultHints() {
hints = new HashMap<>();
hints.put(EncodeHintType.MARGIN,2);
hints.put(EncodeHintType.CHARACTER_SET, DEFAULT_CHARACTER_SET);
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
}
/**
* 设置图片宽高
*
* @param width 图片宽度
* @param height 图片高度
* @return Builder
*/
public Builder size(int width, int height) {
this.width = width;
this.height = height;
return this;
}
/**
* 设置图片宽高
*
* @param size 图片尺寸(width=height=size)
* @return Builder
*/
public Builder size(int size){
return size(size,size);
}
/**
* 设置生成码的颜色
*
* @param onColor 前景色 ARGB
* @param offColor 背景色 ARGB
* @return
*/
public Builder color(int onColor, int offColor) {
this.matrixToImageConfig = new MatrixToImageConfig(onColor, offColor);
return this;
}
/**
* 设置生成内容
*
* @param content 生成内容
* @return Buidler
*/
public Builder content(String content) {
this.content = content;
return this;
}
/**
* 设置EncodeHintType
*
* @param hints
* @return Buidler
*/
public Builder hints(Map
hints) { this.hints.putAll(hints); return this; } /** * 设置生类型 * * @param format 生成类型 * @return Barcode */ public Barcode format(BarcodeFormat format) { this.format = format; return new Barcode(this); } /** * 二维码 * * @return Barcode */ public Barcode qrcode() { return format(BarcodeFormat.QR_CODE); } /** * 二维码 * * @param logo logo图片 * @return Barcode */ public Barcode qrcode(BufferedImage logo) { this.logo = logo; return format(BarcodeFormat.QR_CODE); } /** * 二维码 * * @param logo logo图片文件 * @return Barcode */ public Barcode qrcode(File logo) throws IOException { return qrcode(ImageIO.read(logo)); } /** * 二维码 * * @param logo logo图片URL * @return Barcode */ public Barcode qrcode(URL logo) throws IOException { return qrcode(ImageIO.read(logo)); } /** * 二维码 * * @param logo logo图片输入流 * @return Barcode */ public Barcode qrcode(InputStream logo) throws IOException { return qrcode(ImageIO.read(logo)); } /** * 二维码 * * @param logo logo图片路径 * @return Barcode */ public Barcode qrcode(Path logo) throws IOException { return qrcode(ImageIO.read(logo.toFile())); } } }
调用样例
public static void main(String[] args) {
try {
File logo=new File("...");
Barcode.Builder builder= Barcode.of()
.content("我是二维码生成器啦!啦啦啦啦!!!!啦!啦啦啦啦!!!")
.size(400,400)
.color(0xFFFFFFFF,0xFF00A2FF);
builder.qrcode(logo).generate("jpeg",new File("...."));
//上一步已经设置了logo 所以直接调用 .qrcode
builder.color(0xFF00A2FF,0xFFFFFFFF)
.qrcode().generate("jpg",new File("...."));
} catch (IOException | WriterException e) {
e.printStackTrace();
}
}
