zoukankan      html  css  js  c++  java
  • 【Java 二维码】生成二维码

    ZXingCodeEncodeUtils    生成及解析二维码项目
    package utils;
    
    import java.awt.BasicStroke;
    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.InputStream;
    import java.util.EnumMap;
    
    import javax.imageio.ImageIO;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    /**
     * 生成二维码
     */
    public class ZXingCodeEncodeUtils {
    
        public static void main(String[] args) {
            //        createZXingCodeSaveToDisk("kikyo", 400, 400, "D:/kikyo.gif", "JPEG");
            InputStream logoStream = ZXingCodeEncodeUtils.class.getClassLoader().getResourceAsStream("image/logo.jpg");
            createZxingCodeUseLogoSaveToDisk("kikyo", 400, 400, "D:/kikyo.jpg", "JPEG", logoStream);
            System.out.println("生成成功");
        }
    
        // 二维码颜色
        private static final int BLACK = 0xFF000000;
        // 二维码背景颜色
        private static final int WHITE = 0xFFFFFFFF;
    
        // 二维码格式参数
        private static final EnumMap<EncodeHintType, Object> hints = new EnumMap<EncodeHintType, Object>(EncodeHintType.class);
    
        static {
            /*
             * 二维码的纠错级别(排错率),4个级别: L (7%)、 M (15%)、 Q (25%)、 H (30%)(最高H)
             * 纠错信息同样存储在二维码中,纠错级别越高,纠错信息占用的空间越多,那么能存储的有用讯息就越少;共有四级; 选择M,扫描速度快。
             */
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            // 二维码边界空白大小 1,2,3,4 (4为默认,最大)
            hints.put(EncodeHintType.MARGIN, 1);
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");// 设置放入的字符的编码
        }
    
        /**
         * 生成二维码保存到目标路径
         */
        public static void createZXingCodeSaveToDisk(String content, int width, int height, String savePath, String imageType) {
            try {
                BufferedImage image = createZXingCodeNormal(content, width, height);
                // 保存图片到硬盘
                File file = new File(savePath);
                if (!file.exists()) {
                    file.createNewFile();
                }
                ImageIO.write(image, imageType, file);
                System.out.println("生成成功");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 生成二维码返回图片对象
         */
        public static BufferedImage createZXingCodeNormal(String content, int width, int height) {
            try {
                BitMatrix encode = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
                // 得到二维码的宽度
                int code_width = encode.getWidth();
                int code_height = encode.getHeight();
                // 创建图片
                BufferedImage image = new BufferedImage(code_width, code_height, BufferedImage.TYPE_INT_RGB);
                // 把二维码里面的信息写到图片里面
                for (int i = 0; i < code_width; i++) {
                    for (int j = 0; j < code_height; j++) {
                        image.setRGB(i, j, encode.get(i, j) ? BLACK : WHITE);
                    }
                }
                return image;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
    
        /**
         * 生成一张带logo的二维码
         *
         * @param logoStream logo的流对象
         */
        public static void createZxingCodeUseLogoSaveToDisk(String content, int width, int height, String savePath,
                                                            String imageType, InputStream logoStream) {
            try {
                BufferedImage codeImage = createZxingCodeUseLogo(content, width, height, logoStream);
                // 保存图片到硬盘
                File file = new File(savePath);
                if (!file.exists()) {
                    file.createNewFile();
                }
                ImageIO.write(codeImage, imageType, file);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 生成一张带logo的二维码  返回BuffredeImage
         *
         * @param logoStream logo的流对象
         */
        public static BufferedImage createZxingCodeUseLogo(String content, int width, int height, InputStream logoStream) {
            try {
                //生成二维码图片
                BufferedImage codeNormal = createZXingCodeNormal(content, width, height);
                //判断logoStream是否为空
                if (null == codeNormal || null == logoStream) {
                    System.out.println("codeNormal or logoStream is null");
                    return null;
                }
                //拿到可以操作当前图片的画笔
                Graphics2D graphics = codeNormal.createGraphics();
                //得到logo图片的对象
                BufferedImage logoImage = ImageIO.read(logoStream);
                //得到logo的原始宽高
                int old_logo_width = logoImage.getWidth();
                int old_logo_height = logoImage.getHeight();
    
                //得到二维码的宽高
                int code_width = codeNormal.getWidth();
                int code_height = codeNormal.getHeight();
    
                //算出logo在二维码里面能存在的最大值
                int logo_max_width = code_width / 5;
                int logo_max_height = code_height / 5;
    
                //计算logo的可用宽高
                int logo_width = logo_max_width < old_logo_width ? logo_max_width : old_logo_width;
                int logo_height = logo_max_height < old_logo_height ? logo_max_height : old_logo_height;
    
                //计算logo的开始点的坐标
                int x = (code_width - logo_width) / 2;
                int y = (code_height - logo_height) / 2;
    
                /**
                 * logoImage logo图片对象
                 * x 开始画的x轴坐标
                 * y 开始画的y轴的坐
                 * logo_width 要画的x轴的长度
                 * logo_height 要画的y车的长度
                 * arg5  null
                 */
                graphics.drawImage(logoImage, x, y, logo_width, logo_height, null);
    
                graphics.setStroke(new BasicStroke(2));
                graphics.setColor(Color.WHITE);
                //画白色边框
                graphics.drawRoundRect(x, y, logo_width, logo_height, 15, 15);
                graphics.dispose();//让画上的去的内容生效
                return codeNormal;
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("生成失败  " + e.getMessage());
                return null;
            }
        }
    }
    ZXingCodeDecodeUtils
    package utils;
    
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.InputStream;
    import java.util.EnumMap;
    
    import javax.imageio.ImageIO;
    
    import com.google.zxing.Binarizer;
    import com.google.zxing.BinaryBitmap;
    import com.google.zxing.DecodeHintType;
    import com.google.zxing.LuminanceSource;
    import com.google.zxing.MultiFormatReader;
    import com.google.zxing.Result;
    import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
    import com.google.zxing.common.HybridBinarizer;
    
    /**
     * 解析二维码
     */
    public class ZXingCodeDecodeUtils {
    
        public static void main(String[] args) throws FileNotFoundException {
            //  String string = decodeCodeFile("D:/kikyo.gif");
            String string = decodeCodeStream(new FileInputStream(new File("D:/kikyo.jpg")));
            System.out.println(string);
        }
    
        // 二维码格式参数
        private static final EnumMap<DecodeHintType, Object> decodeHints = new EnumMap<DecodeHintType, Object>(DecodeHintType.class);
    
        static {
            decodeHints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
        }
    
        /**
         * 解析文件
         */
        public static String decodeCodeFile(String path) {
            File file = new File(path);
            if (!file.exists())
                return null;
            // 把文件转成图片对象
            try {
                String content = decodeCodeStream(new FileInputStream(file));
                return content;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
        /**
         * 解析流
         */
        public static String decodeCodeStream(InputStream inputStream) {
            if (null == inputStream)
                return null;
            try {
                BufferedImage image = ImageIO.read(inputStream);
                LuminanceSource source = new BufferedImageLuminanceSource(image);
                Binarizer binarizer = new HybridBinarizer(source);
                BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
                MultiFormatReader reader = new MultiFormatReader();
                Result result = reader.decode(binaryBitmap, decodeHints);
                String content = result.getText();
                return content;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    }
    CodeServlet
    @WebServlet("/code.action")
    public class CodeServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //生成图片
    //        BufferedImage codeImage=ZXingCodeEncodeUtils.createZXingCodeNormal("kikyo", 300, 300);
            InputStream logoStream = this.getClass().getClassLoader().getResourceAsStream("/image/logo.jpg");
            BufferedImage codeImage = ZXingCodeEncodeUtils.createZxingCodeUseLogo("kikyo", 300, 300, logoStream);
    
            ServletOutputStream outputStream = response.getOutputStream();
            ImageIO.write(codeImage, "JPEG", outputStream);
            outputStream.close();
        }
    }
    DeCodeServlet
    @WebServlet("/decode.action")
    @MultipartConfig
    public class DeCodeServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            Part part = request.getPart("mf");
            request.setCharacterEncoding("utf-8");
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
            String string = ZXingCodeDecodeUtils.decodeCodeStream(part.getInputStream());
            PrintWriter out = response.getWriter();
            out.write(string);
            out.flush();
            out.close();
        }
    }

    index.jsp

    <img alt="" src="code.action" >
    <form action="decode.action" method="post" enctype="multipart/form-data">
        <input type="file" name="mf">
        <input type="submit" value="解析">
    </form>

    pom.xml

            <!-- servlet -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.0.1</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>2.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.annotation</groupId>
                <artifactId>javax.annotation-api</artifactId>
                <version>1.2</version>
            </dependency>
            <dependency>
                <groupId>jstl</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>
    
            <!-- ZXing -->
            <dependency>
                <groupId>com.google.zxing</groupId>
                <artifactId>core</artifactId>
                <version>3.3.3</version>
            </dependency>
            <dependency>
                <groupId>com.google.zxing</groupId>
                <artifactId>javase</artifactId>
                <version>3.3.3</version>
            </dependency>
  • 相关阅读:
    RecyclerView的万能适配器+定义可以到底部自动刷新的RecyclerView
    Material Design 摘要
    模版方法模式
    工厂方法模式
    单例模式
    Android中使用Intent和IntentFilter进行通信
    Json/XML/HTML数据解析
    Java中集合总结
    重构笔记
    Android中ActionBar的使用
  • 原文地址:https://www.cnblogs.com/kikyoqiang/p/12250541.html
Copyright © 2011-2022 走看看