Zxing二维码扫描与解析

 

使用二维码创建与解析的时候,必须得先导入zxing.jar或者使用(core-3.4.0.jar以及javase-3.4.0.jar)

 

 

项目总体组成如下:

CodeServlet二维码生成类:

package com.sxt.servlet;

 

 

import com.sxt.utils.ZXingCodeEncodeUtils;

 

 

import javax.imageio.ImageIO;

import javax.servlet.ServletException;

import javax.servlet.ServletOutputStream;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.awt.image.BufferedImage;

import java.io.IOException;

import java.io.InputStream;

import java.io.PrintWriter;

 

 

@WebServlet("/code.action")

public class CodeServlet extends HttpServlet {

    @Override

    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //生成图片

       //BufferedImage codeImage= ZXingCodeEncodeUtils.createZXingCodeNormal("洲洲",300,300);

        InputStream logoStream=ZXingCodeEncodeUtils.class.getClassLoader().getResourceAsStream("4.jpg");

 

 

        BufferedImage codeImage=ZXingCodeEncodeUtils.createZxingCodeUseLogo("洲洲",300,300,logoStream);

        ServletOutputStream outputStream=resp.getOutputStream();

 

 

        ImageIO.write(codeImage,"JPEG",outputStream);

        outputStream.close();

 

 

    }

}

DeCodeServlet二维码解析类:

package com.sxt.servlet;

 

 

import com.sxt.utils.ZXingCodeDecodeUtils;

import com.sxt.utils.ZXingCodeEncodeUtils;

 

 

import javax.servlet.ServletException;

import javax.servlet.annotation.MultipartConfig;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.Part;

import java.io.IOException;

import java.io.PrintWriter;

 

 

@WebServlet("/decode.action")

@MultipartConfig

public class DeCodeServlet extends HttpServlet {

    @Override

    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        Part part=req.getPart("mf");

        req.setCharacterEncoding("utf-8");

        resp.setCharacterEncoding("utf-8");

        resp.setContentType("text/html;charset=utf-8");

        String string=ZXingCodeDecodeUtils.decodeCodeStream(part.getInputStream());

        PrintWriter out=resp.getWriter();

        out.write(string);

        out.flush();

        out.close();

    }

}

ZXingCodeEncodeUtils二维码生成工具类

package com.sxt.utils;

 

 

import com.google.zxing.BarcodeFormat;

import com.google.zxing.EncodeHintType;

import com.google.zxing.MultiFormatWriter;

import com.google.zxing.WriterException;

import com.google.zxing.common.BitMatrix;

import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

 

 

import javax.imageio.ImageIO;

import java.awt.*;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.util.EnumMap;

 

 

/**

* 生成二维码

*/

public class ZXingCodeEncodeUtils {

    //声明颜色

    //二维码颜色

    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");//设置放入字符的编码

    }

    /**

     * 生成二维码保存到D盘

     */

    public static void createZXingSaveToDisk(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();

        }

    }

 

 

 

 

 

 

 

 

    /**

     * 生成二维码,返回图片对象

     * @param content

     * @param width

     * @param height

     */

    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);

                }

            }

            System.out.println("生成成功");

            return image;

        } catch (Exception e) {

            e.printStackTrace();

        }

        return  null;

    }

 

 

    /**

     * 生成一张带logo的二维码

     * logoStream:logo流对象

     */

    public static void createZxingCodeUseLogoSaveDisk(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);

                    System.out.println("生成成功");

                } catch (IOException e) {

                    e.printStackTrace();

                    return;

                }

 

 

 

 

    }

 

 

    public static BufferedImage createZxingCodeUseLogo(String content, int width, int height, InputStream logoStream){

        //生成二维码图片

        BufferedImage codeNormal= createZXingCodeNormal(content,width,height);

        BufferedImage logoImage;

        if(codeNormal!=null){

            //判断logoStream是否为空

            if(logoStream!=null){

                //拿到可以操作当前图片的画笔

                Graphics2D graphics=codeNormal.createGraphics();

                try {

                    //得到logo图片的原始对象

                    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;

 

 

                    /**

                     * arg0:logo图片对象

                     * arg1:开始画的x轴坐标

                     * arg2:开始画的y轴坐标

                     * arg3:要画的x轴的长度

                     * arg4:要画的y轴的长度

                     * arg5  null

                     */

                    graphics.drawImage(logoImage,x,y,logo_width,logo_height,null);

                    graphics.setStroke(new BasicStroke(2));

                    graphics.setColor(Color.RED);

                    //画白色边框

                    graphics.drawRoundRect(x,y,logo_width,logo_height,15,15);

 

 

                    graphics.dispose();//让画上去的内容生效

                    return codeNormal;

 

 

                } catch (IOException e) {

                    e.printStackTrace();

                    System.out.println("生成失败");

                }

//                把logoStream转成图片对象

 

 

 

 

            }

        }else {

            System.out.println("生成失败");

 

 

        }

        return null;

    }

 

 

 

 

 

 

 

 

    public static void main(String[] args) {

//        createZXingSaveToDisk("洲洲",400,

//                400,"D:/image/zhouzhou.gif",

//                "JPEG");

        InputStream logoStream=ZXingCodeEncodeUtils.class.getClassLoader().getResourceAsStream("4.jpg");

        createZxingCodeUseLogoSaveDisk("洲洲",400,400,"D:/image/zhouzhou.gif", "JPEG",logoStream);

    }

}

 

 

 

ZXingCodeDecodeUtils二维码解析类

 

package com.sxt.utils;

 

 

import com.google.zxing.*;

import com.google.zxing.client.j2se.BufferedImageLuminanceSource;

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.util.EnumMap;

 

 

/**

* 解析二维码

*/

public class ZXingCodeDecodeUtils {

 

 

    //二维码格式参数

    private static final EnumMap<DecodeHintType,Object>decodeHints=new EnumMap<DecodeHintType, Object>(DecodeHintType.class);

 

 

    static {

        decodeHints.put(DecodeHintType.CHARACTER_SET,"UTF-8");

    }

 

 

    /**

     * 解析文件

     * @param args

     */

    public static String decodeCodeFile(String path){

        File file=new File(path);

        if(file.exists()){

            //把文件转成图片对象

            try {

 

 

                String context=decodeCodeStream(new FileInputStream(file));

                return context;

            } catch (Exception e) {

                e.printStackTrace();

                return null;

            }

        }else {

            return  null;

        }

    }

    /**

     * 解析流

     * @param args

     */

    public static String decodeCodeStream(InputStream is){

        if(is!=null){

            try {

                BufferedImage image=ImageIO.read(is);

                //解析二维码

                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 context=result.getText();

                return context;

            }catch (Exception e){

                e.printStackTrace();

                return  null;

            }

        }else {

            return null;

        }

    }

    public static void main(String[] args) throws FileNotFoundException {

//        System.out.println(decodeCodeFile("D:/image/zhouzhou.gif"));

        System.out.println(decodeCodeStream(new FileInputStream(new File("D:/image/zhouzhou.gif"))));

    }

}

前端页面:

<%--

  Created by IntelliJ IDEA.

  User: Lenovo

  Date: 2019/10/26

  Time: 10:25

  To change this template use File | Settings | File Templates.

--%>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>

  <head>

    <title>$Title$</title>

  </head>

  <body>

      <img src="/code.action">

 

 

 

 

      <form action="/decode.action" method="post" enctype="multipart/form-data">

        <input type="file" name="mf">

        <input type="submit" value="解析">

      </form>

  </body>

</html>

运行结果如下:

手机扫描结果:

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值