基于zxing的二维码、条码生成、解析工具类,可设置生成码颜色及二维码logo,链式调用

2018-12-26

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.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();
        }
    }

下载地址

百度网盘
密码:

相关推荐

java读取excel
java

2018-12-26

RSA工具类
java

2018-12-27