zoukankan      html  css  js  c++  java
  • 二维码工具类

    二维码工具类,提供多种生成二维码、解析二维码的方法,包括中间logo的二维码等方法。

    源码如下:(点击下载 - QrcodeUtils.javaMatrixToImageWriterEx.javaMatrixToLogoImageConfig.javacommons-io-2.4.jarcommons-lang-2.6.jarslf4j-api-1.7.12.jarjavase-3.1.0.jarcore-3.1.0.jar 、FolderUtils.java)

    QrcodeUtils.java 源码:

    import java.awt.Color;
    import java.awt.image.BufferedImage;
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.URL;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
    import javax.imageio.ImageIO;
    import org.apache.commons.io.FilenameUtils;
    import org.apache.commons.io.IOUtils;
    import org.apache.commons.lang.ArrayUtils;
    import org.apache.commons.lang.StringUtils;
    import org.apache.commons.lang.SystemUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import com.google.zxing.BinaryBitmap;
    import com.google.zxing.DecodeHintType;
    import com.google.zxing.LuminanceSource;
    import com.google.zxing.MultiFormatReader;
    import com.google.zxing.Reader;
    import com.google.zxing.ReaderException;
    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;
    
    /**
     * 二维码工具类
     * 
     */
    public class QrcodeUtils {
    
        private static final transient Logger LOGGER = LoggerFactory.getLogger(QrcodeUtils.class);
    
        private static transient String DEFAULT_FORMAT = "jpg";
        private static transient int DEFAULT_WIDTH = 200;
        private static transient int DEFAULT_HEIGHT = 200;
    
        static {
            try {
                final String[] foo = new String[] { "240", "240" };
                final String format = "jpg";
                if (StringUtils.isNotBlank(format)) {
                    DEFAULT_FORMAT = StringUtils.strip(format).toLowerCase();
                }
    
                if (ArrayUtils.isNotEmpty(foo) && foo.length == 2) {
                    Integer tmpWidth = Integer.valueOf(foo[0]);
                    Integer tmpHeight = Integer.valueOf(foo[1]);
                    if (tmpWidth > 0 && tmpHeight > 0) {
                        DEFAULT_WIDTH = tmpWidth;
                        DEFAULT_HEIGHT = tmpHeight;
                    } else {
                        LOGGER.warn("qrcode size must be lager than zero.");
                    }
                }
            } catch (Throwable e) {
                LOGGER.warn("read default qrcode size config error: ", e);
            }
        }
    
        /**
         * 生成二维码(无中间logo)
         * 
         * @param content
         *            二维码文本内容
         * @param destFile
         *            输出文件
         */
        public static final void gen(final String content, File destFile) throws Exception {
            gen(content, destFile, DEFAULT_WIDTH, DEFAULT_HEIGHT);
        }
    
        /**
         * 生成二维码
         * 
         * @param content
         *            二维码文本内容
         * @param destFile
         *            目的文件
         * @param logoFile
         *            中间logo文件
         * 
         */
        public static final void gen(final String content, final File destFile, final File logoFile) throws Exception {
            gen(content, destFile, logoFile, DEFAULT_WIDTH, DEFAULT_HEIGHT);
        }
    
        /**
         * 生成二维码
         * 
         * @param content
         *            二维码文本内容
         * @param destFile
         *            目的文件
         * @param logoFile
         *            中间logo文件
         * @param width
         *            宽度
         * @param height
         *            高度
         */
        public static final void gen(final String content, final File destFile,
                final File logoFile, int width, int height) throws Exception {
            FolderUtils.mkdirs(destFile.getParent());
            OutputStream output = null;
            InputStream input = null;
            try {
                output = new BufferedOutputStream(new FileOutputStream(destFile));
                if (logoFile != null && logoFile.exists() && logoFile.isFile()) {
                    input = new BufferedInputStream(new FileInputStream(logoFile));
                }
                gen(content, output, input, width, height);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                throw new Exception(e);
            } finally {
                IOUtils.closeQuietly(output);
                IOUtils.closeQuietly(input);
            }
        }
    
        /**
         * 生成二维码(无中间logo)
         * 
         * @param content
         *            二维码文本内容
         * @param destFile
         *            输出文件
         * @param width
         *            宽度
         * @param height
         *            高度
         */
        public static final void gen(final String content, File destFile, int width, int height) throws Exception {
            FolderUtils.mkdirs(destFile.getParent());
            OutputStream output = null;
            try {
                output = new BufferedOutputStream(new FileOutputStream(destFile));
                gen(content, output, width, height);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                throw new Exception(e);
            } catch (Exception e) {
                throw e;
            } finally {
                IOUtils.closeQuietly(output);
            }
        }
    
        /**
         * 生成二维码
         * 
         * @param content
         *            二维码文本内容
         * @param output
         *            输出流
         */
        public static final void gen(final String content, final OutputStream output) throws Exception {
            gen(content, output, DEFAULT_WIDTH, DEFAULT_HEIGHT);
        }
    
        /**
         * 生成二维码
         * 
         * @param content
         *            二维码文本内容
         * @param output
         *            输出流
         * @param logoInput
         *            中间logo输入流,为空时中间无logo
         */
        public static final void gen(final String content,
                final OutputStream output, final InputStream logoInput) throws Exception {
            gen(content, output, logoInput, DEFAULT_WIDTH, DEFAULT_HEIGHT);
        }
    
        /**
         * 生成二维码
         * 
         * @param content
         *            二维码文本内容
         * @param output
         *            输出流
         * @param logoInput
         *            中间logo输入流,为空时中间无logo
         * @param width
         *            宽度
         * @param height
         *            高度
         */
        public static final void gen(final String content,
                final OutputStream output, final InputStream logoInput, int width, int height) throws Exception {
            gen(content, output, logoInput, width, height, ErrorCorrectionLevel.M);
        }
    
        /**
         * 生成二维码
         * 
         * @param content
         *            二维码文本内容
         * @param output
         *            输出流
         * @param logoInput
         *            中间logo输入流,为空时中间无logo
         * @param width
         *            宽度
         * @param height
         *            高度
         * @param errorCorrectionLevel
         *            容错级别
         */
        public static final void gen(final String content,
                final OutputStream output, final InputStream logoInput, int width,
                int height, ErrorCorrectionLevel errorCorrectionLevel) throws Exception {
            if (StringUtils.isEmpty(content)) {
                throw new IllegalArgumentException("qr code content cannot be empty.");
            }
            if (output == null) {
                throw new IllegalArgumentException("qr code output stream cannot be null.");
            }
    
            final BitMatrix matrix = MatrixToImageWriterEx.createQRCode(content, width, height, errorCorrectionLevel);
    
            if (logoInput == null) {
                try {
                    MatrixToImageWriter.writeToStream(matrix, DEFAULT_FORMAT, output);
                    return;
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new Exception(e);
                }
            }
    
            final MatrixToLogoImageConfig logoConfig = new MatrixToLogoImageConfig(Color.BLUE, 4);
    
            final String destPath = FilenameUtils.normalizeNoEndSeparator(SystemUtils.getJavaIoTmpDir()
                            + File.separator + UUID.randomUUID().toString()
                            + ".tmp");
            InputStream tmpInput = null;
            final File destFile = new File(destPath);
            try {
                MatrixToImageWriterEx.writeToFile(matrix, DEFAULT_FORMAT, destPath, logoInput, logoConfig);
                tmpInput = new BufferedInputStream(new FileInputStream(destFile));
                IOUtils.copy(tmpInput, output);
            } catch (IOException e) {
                e.printStackTrace();
                throw new Exception(e);
            } finally {
                IOUtils.closeQuietly(tmpInput);
                destFile.delete();
            }
        }
    
        /**
         * 生成二维码
         * 
         * @param content
         *            二维码文本内容
         * @param output
         *            输出流
         * @param width
         *            宽度
         * @param height
         *            高度
         */
        public static final void gen(final String content, final OutputStream output, int width, int height) throws Exception {
            gen(content, output, null, width, height);
        }
    
        /**
         * 生成二维码
         * 
         * @param content
         *            二维码文本内容
         * @param destPath
         *            输出文件路径
         */
        public static final void gen(final String content, final String destPath) throws Exception {
            gen(content, destPath, DEFAULT_WIDTH, DEFAULT_HEIGHT);
        }
    
        /**
         * 生成二维码
         * 
         * @param content
         *            二维码文本内容
         * @param destPath
         *            输出文件路径
         * @param width
         *            宽度
         * @param height
         *            高度
         */
        public static final void gen(final String content, final String destPath, int width, int height) throws Exception {
            gen(content, new File(destPath), width, height);
        }
    
        /**
         * 生成二维码
         * 
         * @param content
         *            二维码文本内容
         * @param destPath
         *            目的文件路径
         * @param logoPath
         *            中间logo文件路径
         */
        public static final void gen(final String content, final String destPath, final String logoPath) throws Exception {
            gen(content, destPath, logoPath, DEFAULT_WIDTH, DEFAULT_HEIGHT);
        }
    
        /**
         * 生成二维码
         * 
         * @param content
         *            二维码文本内容
         * @param destPath
         *            目的文件路径
         * @param logoPath
         *            中间logo文件路径
         * @param width
         *            宽度
         * @param height
         *            高度
         */
        public static final void gen(final String content, final String destPath,
                final String logoPath, int width, int height) throws Exception {
            File foo = new File(destPath);
            File bar = new File(logoPath);
            gen(content, foo, bar, width, height);
        }
    
        /**
         * 解析二维码
         * 
         * @param input
         *            二维码输入流
         */
        public static final String parse(InputStream input) throws Exception {
            Reader reader = null;
            BufferedImage image;
            try {
                image = ImageIO.read(input);
                if (image == null) {
                    throw new Exception("cannot read image from inputstream.");
                }
                final LuminanceSource source = new BufferedImageLuminanceSource(image);
                final BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
                final Map<DecodeHintType, String> hints = new HashMap<DecodeHintType, String>();
                hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
                // 解码设置编码方式为:utf-8,
                reader = new MultiFormatReader();
                return reader.decode(bitmap, hints).getText();
            } catch (IOException e) {
                e.printStackTrace();
                throw new Exception("parse QR code error: ", e);
            } catch (ReaderException e) {
                e.printStackTrace();
                throw new Exception("parse QR code error: ", e);
            }
        }
    
        /**
         * 解析二维码
         * 
         * @param url
         *            二维码url
         */
        public static final String parse(URL url) throws Exception {
            InputStream in = null;
            try {
                in = url.openStream();
                return parse(in);
            } catch (IOException e) {
                e.printStackTrace();
                throw new Exception("parse QR code error: ", e);
            } finally {
                IOUtils.closeQuietly(in);
            }
        }
    
        /**
         * 解析二维码
         * 
         * @param file
         *            二维码图片文件
         */
        public static final String parse(File file) throws Exception {
            InputStream in = null;
            try {
                in = new BufferedInputStream(new FileInputStream(file));
                return parse(in);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                throw new Exception("parse QR code error: ", e);
            } finally {
                IOUtils.closeQuietly(in);
            }
        }
    
        /**
         * 解析二维码
         * 
         * @param filePath
         *            二维码图片文件路径
         */
        public static final String parse(String filePath) throws Exception {
            InputStream in = null;
            try {
                in = new BufferedInputStream(new FileInputStream(filePath));
                return parse(in);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                throw new Exception("parse QR code error: ", e);
            } finally {
                IOUtils.closeQuietly(in);
            }
        }
    }

    MatrixToImageWriterEx.java 源码:

    import java.awt.BasicStroke;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Hashtable;
    import javax.imageio.ImageIO;
    import org.apache.commons.io.IOUtils;
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.WriterException;
    import com.google.zxing.client.j2se.MatrixToImageConfig;
    import com.google.zxing.client.j2se.MatrixToImageWriter;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    class MatrixToImageWriterEx {
    
        private static final MatrixToLogoImageConfig DEFAULT_CONFIG = new MatrixToLogoImageConfig();
    
        /**
         * 根据内容生成二维码数据
         * 
         * @param content
         *            二维码文字内容[为了信息安全性,一般都要先进行数据加密]
         * @param width
         *            二维码照片宽度
         * @param height
         *            二维码照片高度
         * @param errorCorrectionLevel
         *            纠错等级
         * @return a {@link com.google.zxing.common.BitMatrix} object.
         * @since 0.0.7
         */
        public static BitMatrix createQRCode(String content, int width, int height,
                ErrorCorrectionLevel errorCorrectionLevel) {
            Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
            // 设置字符编码
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            // 指定纠错等级
            hints.put(EncodeHintType.ERROR_CORRECTION, errorCorrectionLevel);
            BitMatrix matrix = null;
            try {
                matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
            } catch (WriterException e) {
                e.printStackTrace();
            }
            return matrix;
        }
    
        /**
         * 根据内容生成二维码数据
         * 
         * @param content
         *            二维码文字内容[为了信息安全性,一般都要先进行数据加密]
         * @param width
         *            二维码照片宽度
         * @param height
         *            二维码照片高度
         * @return a {@link com.google.zxing.common.BitMatrix} object.
         * @since 0.0.7
         */
        public static BitMatrix createQRCode(String content, int width, int height) {
            return createQRCode(content, width, height, ErrorCorrectionLevel.H);
        }
    
        /**
         * 写入二维码、以及将照片logo写入二维码中
         * 
         * @param matrix
         *            要写入的二维码
         * @param format
         *            二维码照片格式
         * @param imagePath
         *            二维码照片保存路径
         * @param logoPath
         *            logo路径
         * @throws java.io.IOException
         *             if any.
         * @since 0.0.7
         */
        public static void writeToFile(BitMatrix matrix, String format,
                String imagePath, String logoPath) throws IOException {
            InputStream input = null;
            try {
                input = new BufferedInputStream(new FileInputStream(logoPath));
                writeToFile(matrix, format, imagePath, input);
            } catch (IOException e) {
                throw e;
            } finally {
                IOUtils.closeQuietly(input);
            }
    
        }
    
        /**
         * <p>
         * writeToFile.
         * </p>
         * 
         * @param matrix
         *            a {@link com.google.zxing.common.BitMatrix} object.
         * @param format
         *            a {@link java.lang.String} object.
         * @param imagePath
         *            a {@link java.lang.String} object.
         * @param logoInputStream
         *            a {@link java.io.InputStream} object.
         * @throws java.io.IOException
         *             if any.
         * @since 0.0.7
         */
        public static void writeToFile(BitMatrix matrix, String format,
                String imagePath, InputStream logoInputStream) throws IOException {
            MatrixToImageWriter.writeToPath(matrix, format, new File(imagePath).toPath(), new MatrixToImageConfig());
            // 添加logo图片, 此处一定需要重新进行读取,而不能直接使用二维码的BufferedImage 对象
            BufferedImage img = ImageIO.read(new File(imagePath));
            MatrixToImageWriterEx.overlapImage(img, format, imagePath, logoInputStream, DEFAULT_CONFIG);
        }
    
        /**
         * 写入二维码、以及将照片logo写入二维码中
         * 
         * @param matrix
         *            要写入的二维码
         * @param format
         *            二维码照片格式
         * @param imagePath
         *            二维码照片保存路径
         * @param logoPath
         *            logo路径
         * @param logoConfig
         *            logo配置对象
         * @throws java.io.IOException
         *             if any.
         * @since 0.0.7
         */
        public static void writeToFile(BitMatrix matrix, String format, String imagePath, InputStream logoPath,
                MatrixToLogoImageConfig logoConfig) throws IOException {
            MatrixToImageWriter.writeToPath(matrix, format, new File(imagePath).toPath(), new MatrixToImageConfig());
            // 添加logo图片, 此处一定需要重新进行读取,而不能直接使用二维码的BufferedImage 对象
            BufferedImage img = ImageIO.read(new File(imagePath));
            MatrixToImageWriterEx.overlapImage(img, format, imagePath, logoPath, logoConfig);
        }
    
        /**
         * 将照片logo添加到二维码中间
         * 
         * @param image
         *            生成的二维码照片对象
         * @param imagePath
         *            照片保存路径
         * @param imagePath
         *            照片保存路径
         * @param imagePath
         *            照片保存路径
         * @param imagePath
         *            照片保存路径
         * @param imagePath
         *            照片保存路径
         * @param imagePath
         *            照片保存路径
         * @param logoInputStream
         *            logo输入流
         * @param formate
         *            照片格式
         * @param logoConfig
         *            a {@link cn.yicha.commons.qrcode.MatrixToLogoImageConfig}
         *            object.
         * @since 0.0.7
         */
        public static void overlapImage(BufferedImage image, String formate,
                String imagePath, InputStream logoInputStream,
                MatrixToLogoImageConfig logoConfig) {
            try {
                BufferedImage logo = ImageIO.read(logoInputStream);
                Graphics2D g = image.createGraphics();
                // 考虑到logo照片贴到二维码中,建议大小不要超过二维码的1/5;
                int width = image.getWidth() / logoConfig.getLogoPart();
                int height = image.getHeight() / logoConfig.getLogoPart();
                // logo起始位置,此目的是为logo居中显示
                int x = (image.getWidth() - width) / 2;
                int y = (image.getHeight() - height) / 2;
                // 绘制图
                g.drawImage(logo, x, y, width, height, null);
    
                // 给logo画边框
                // 构造一个具有指定线条宽度以及 cap 和 join 风格的默认值的实心 BasicStroke
                g.setStroke(new BasicStroke(logoConfig.getBorder()));
                g.setColor(logoConfig.getBorderColor());
                g.drawRect(x, y, width, height);
    
                g.dispose();
                // 写入logo照片到二维码
                ImageIO.write(image, formate, new File(imagePath));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }

    MatrixToLogoImageConfig.java 源码:

    import java.awt.Color;
    
    class MatrixToLogoImageConfig {
        // logo默认边框颜色
        /** Constant <code>DEFAULT_BORDERCOLOR</code> */
        public static final Color DEFAULT_BORDERCOLOR = Color.RED;
        // logo默认边框宽度
        /** Constant <code>DEFAULT_BORDER=2</code> */
        public static final int DEFAULT_BORDER = 2;
        // logo大小默认为照片的1/5
        /** Constant <code>DEFAULT_LOGOPART=5</code> */
        public static final int DEFAULT_LOGOPART = 5;
    
        private final int border = DEFAULT_BORDER;
        private final Color borderColor;
        private final int logoPart;
    
        /**
         * Creates a default config with on color {@link #BLACK} and off color
         * {@link #WHITE}, generating normal black-on-white barcodes.
         * 
         * @since 0.0.7
         */
        public MatrixToLogoImageConfig() {
            this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART);
        }
    
        /**
         * <p>
         * Constructor for MatrixToLogoImageConfig.
         * </p>
         * 
         * @param borderColor
         *            a {@link java.awt.Color} object.
         * @param logoPart
         *            a int.
         * @since 0.0.7
         */
        public MatrixToLogoImageConfig(Color borderColor, int logoPart) {
            this.borderColor = borderColor;
            this.logoPart = logoPart;
        }
    
        /**
         * <p>
         * Getter for the field <code>borderColor</code>.
         * </p>
         * 
         * @return a {@link java.awt.Color} object.
         * @since 0.0.7
         */
        public Color getBorderColor() {
            return borderColor;
        }
    
        /**
         * <p>
         * Getter for the field <code>border</code>.
         * </p>
         * 
         * @return a int.
         * @since 0.0.7
         */
        public int getBorder() {
            return border;
        }
    
        /**
         * <p>
         * Getter for the field <code>logoPart</code>.
         * </p>
         * 
         * @return a int.
         * @since 0.0.7
         */
        public int getLogoPart() {
            return logoPart;
        }
    }

    转自:小周的博客

  • 相关阅读:
    【Socket】linux无连接编程技术
    【Socket】linux套接字技术之tcp
    【线程】linux之多线程同步互斥技术
    【线程】linux之thread错误解决方案
    【消息】linux之消息队列
    【Mysql】linux连接mysql错误解决方案
    【Mysql】Fedora下 Mysql 安装及配置
    hdu2457
    hnu10104
    hdu4117
  • 原文地址:https://www.cnblogs.com/lr393993507/p/5455945.html
Copyright © 2011-2022 走看看