美文网首页
Java 生成二维码及带logo的二维码

Java 生成二维码及带logo的二维码

作者: FX_SKY | 来源:发表于2017-07-28 15:36 被阅读786次

    使用ZXing 生成二维码及带logo的二维码。

    ZXing简介

    ZXing是一款开源的优秀二维码编码&解码库,支持javase和Android集成, github地址:https://github.com/zxing/zxing

    效果图

    15.png

    maven依赖

    <dependency>
        <groupId>com.google.zxing</groupId>
        <artifactId>core</artifactId>
        <version>3.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.zxing</groupId>
        <artifactId>javase</artifactId>
        <version>3.3.0</version>
    </dependency>
    

    代码实现

    1. QRCodeService

    package apple.springmvc.zxing.service;
    import com.google.zxing.*;
    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;
    import com.sun.image.codec.jpeg.JPEGCodec;
    import com.sun.image.codec.jpeg.JPEGImageEncoder;
    import org.springframework.stereotype.Service;
    
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.geom.RoundRectangle2D;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @author Ricky Fung
     */
    @Service
    public class QRCodeService {
    
        private static final String CHARSET = "UTF-8";
    
        public File encode(String contents, int width, int height, File qrFile) {
            //生成条形码时的一些配置
            Map<EncodeHintType, Object> hints = new HashMap<>();
            // 指定纠错等级,纠错级别(L 7%、M 15%、Q 25%、H 30%)
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            // 内容所使用字符集编码
            hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
    
            BitMatrix bitMatrix;
            try {
                OutputStream out = new FileOutputStream(qrFile);
                // 生成二维码
                bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
                MatrixToImageWriter.writeToStream(bitMatrix, "png", out);
                out.flush();
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return qrFile;
        }
    
        public File encodeWithLogo(File qrFile, File logoFile, File newQrFile) {
            OutputStream os = null ;
            try {
                Image image2 = ImageIO.read(qrFile) ;
                int width = image2.getWidth(null) ;
                int height = image2.getHeight(null) ;
                BufferedImage bufferImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB) ;
                //BufferedImage bufferImage =ImageIO.read(image) ;
                Graphics2D g2 = bufferImage.createGraphics();
                g2.drawImage(image2, 0, 0, width, height, null) ;
                int matrixWidth = bufferImage.getWidth();
                int matrixHeigh = bufferImage.getHeight();
    
                //读取Logo图片
                BufferedImage logo= ImageIO.read(logoFile);
                //开始绘制图片
                g2.drawImage(logo,matrixWidth/5*2,matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5, null);//绘制
                BasicStroke stroke = new BasicStroke(5,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
                g2.setStroke(stroke);// 设置笔画对象
                //指定弧度的圆角矩形
                RoundRectangle2D.Float round = new RoundRectangle2D.Float(matrixWidth/5*2, matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5,20,20);
                g2.setColor(Color.white);
                g2.draw(round);// 绘制圆弧矩形
    
                //设置logo 有一道灰色边框
                BasicStroke stroke2 = new BasicStroke(1,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
                g2.setStroke(stroke2);// 设置笔画对象
                RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(matrixWidth/5*2+2, matrixHeigh/5*2+2, matrixWidth/5-4, matrixHeigh/5-4,20,20);
                g2.setColor(new Color(128,128,128));
                g2.draw(round2);// 绘制圆弧矩形
    
                g2.dispose();
    
                bufferImage.flush() ;
                os = new FileOutputStream(newQrFile) ;
                JPEGImageEncoder en = JPEGCodec.createJPEGEncoder(os) ;
                en.encode(bufferImage) ;
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if(os!=null) {
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return newQrFile ;
        }
    
        /**
         * ZXing解码
         * @param qrFile
         * @return
         */
        public String decode(File qrFile) {
            BufferedImage image = null;
            Result result = null;
            try {
                image = ImageIO.read(qrFile);
                if (image == null) {
                    System.out.println("the decode image may be not exit.");
                }
                LuminanceSource source = new BufferedImageLuminanceSource(image);
                BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
    
                Map<DecodeHintType, Object> hints = new HashMap<>();
                hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
    
                result = new MultiFormatReader().decode(bitmap, hints);
                return result.getText();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result.getText() ;
        }
    }
    
    

    2. QRCodeController

    package apple.springmvc.zxing.controller;
    
    import apple.springmvc.zxing.model.User;
    import apple.springmvc.zxing.service.QRCodeService;
    import apple.springmvc.zxing.service.UserService;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import java.io.File;
    
    /**
     * @author Ricky Fung
     */
    @Controller
    @RequestMapping("/qr")
    public class QRCodeController {
        private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
        private String uploadPath = "/images" ;
        private int width = 300;
        private int height = 300;
    
        @Autowired
        private UserService userService;
    
        @Autowired
        private QRCodeService qrCodeService;
    
        @RequestMapping(value = "/encode/{userId}", method = RequestMethod.GET)
        public ModelAndView genQR(@PathVariable Long userId, HttpServletRequest request){
    
            User user =  userService.getUser(userId);
    
            String realUploadPath = request.getServletContext().getRealPath(uploadPath);
            logger.info("realUploadPath:{}", realUploadPath);
    
            File uploadDir = new File(realUploadPath);
            if(!uploadDir.exists()) {
                uploadDir.mkdirs();
            }
    
            String imageName = String.format("%s_qr.png", userId);
            File qrFile = new File(uploadDir, imageName);
            qrCodeService.encode(user.toString(), width, height, qrFile);
            logger.info("生成的二维码文件:{}", qrFile.getAbsolutePath());
    
    
            File logoFile = new File(uploadDir, "logo.png");
            imageName = String.format("%s_qr_logo.png", userId);
            File logoQrFile = new File(uploadDir, imageName);
            qrCodeService.encodeWithLogo(qrFile, logoFile, logoQrFile);
            logger.info("生成的带logo二维码文件:{}", logoQrFile.getAbsolutePath());
    
            ModelAndView mv = new ModelAndView("show_qr");
            mv.addObject("userId", userId);
            mv.addObject("qrImage", uploadPath+"/"+qrFile.getName());
            mv.addObject("logoQRImage", uploadPath+"/"+logoQrFile.getName());
            return mv;
        }
    
        @RequestMapping(value = "/decode/{userId}", method = RequestMethod.GET)
        public ModelAndView decodeQR(@PathVariable Long userId, HttpServletRequest request){
            User user =  userService.getUser(userId);
    
            String realUploadPath = request.getServletContext().getRealPath(uploadPath) ;
            File uploadDir = new File(realUploadPath);
    
            String imageName = String.format("%s_qr.png", userId);
            File qrFile = new File(uploadDir, imageName);
            String result = qrCodeService.decode(qrFile);
    
            ModelAndView mv = new ModelAndView("decode_qr") ;
            mv.addObject("result", result);
            return mv;
        }
    }
    

    3. spring-mvc.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
        <mvc:annotation-driven/>
        <context:component-scan base-package="apple.springmvc.zxing.controller">
        </context:component-scan>
    
        <mvc:resources location="/images/" mapping="/images/**"/>
        <mvc:resources location="/js/" mapping="/js/**"/>
        <mvc:default-servlet-handler />
    
        <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
            <property name="viewClass"
                      value="org.springframework.web.servlet.view.JstlView" />
            <property name="prefix" value="/WEB-INF/pages/" />
            <property name="suffix" value=".jsp" />
        </bean>
    
    </beans>
    

    4. jsp页面

    4.1 show_qr.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>二维码与带Logo的二维码</title>
    </head>
    <body>
    <div>
        <div align="center">
            <a href="${pageContext.request.contextPath}/qr/decode/${userId }">
                ![](${pageContext.request.contextPath}${qrImage})
                <b class="btn btn-success" >我要解码</b>
            </a>
        </div>
        <div align="center">
            <a href="${pageContext.request.contextPath}/qr/decode/${userId }">
                ![](${pageContext.request.contextPath}${logoQRImage})
                <b class="btn btn-success" >我要解码</b>
            </a>
        </div>
    </div>
    </body>
    </html>
    
    

    4.2 decode_qr.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>二维码解码结果</title>
    </head>
    <body>
    <div>
        <div align="center">
            <br><br>
            <p>${result}</p>
        </div>
    </div>
    </body>
    </html>
    

    源码

    下载链接:https://github.com/TiFG/springmvc-tutorials/tree/master/springmvc-zxing-demo

    相关文章

      网友评论

          本文标题:Java 生成二维码及带logo的二维码

          本文链接:https://www.haomeiwen.com/subject/dhqflxtx.html