Java 實現二維碼及有Logo 的二維碼(SpringMVC+Zxing+Jsp)

需求:我們需要把訂單信息生成二維碼及有Logo 的二維碼。

先看下效果圖

提交訂單

這裏寫圖片描述

生成二維碼

這裏寫圖片描述

解析二維碼

這裏寫圖片描述

Zxing簡介

本次我們使用優秀的開源利器– ZXing,相比而言它更加靈活方便,可以實現多種編碼格式。

官網:http://code.google.com/p/zxing/

當然我們需要用到了源碼中core和javase下面的相關的架包:

core-3.2.0.jar
javase-3.2.0.jar

都準備好了我們開始編寫了。。。

代碼編寫

SpringMVC 配置可以看我的 SpringMVC 案例

Java 實現圖片水印之文字水印(SpringMVC + Jsp)

Java 實現圖片水印之水印圖片(SpringMVC + Jsp)

不多說了。。

1.先寫Service類

生成二維碼
CoderService.java

package com.wenteryan.service;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

@Service
public class CoderService {

    public String encode(String contents, int width, int height, String uploadPath, String realUploadPath, String imageName) {  
        //生成條形碼時的一些配置
        Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();  
        // 指定糾錯等級,糾錯級別(L 7%、M 15%、Q 25%、H 30%)  
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);  
        // 內容所使用字符集編碼  
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");     

        OutputStream out=null;
        try {
            if(realUploadPath!=null&&realUploadPath!=""){

                out = new FileOutputStream(realUploadPath+"/"+imageName);
            }
        } catch (FileNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        BitMatrix bitMatrix;
        try {
            // 生成二維碼  
            bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
            MatrixToImageWriter.writeToStream(bitMatrix, "png", out);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return uploadPath+"/"+imageName ;
    }  
}

添加Logo
LogoConfig .java

package com.wenteryan.service;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.imageio.ImageIO;

import org.springframework.stereotype.Service;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

@Service
public class LogoConfig {

     public String LogoMatrix(File image, String uploadPath, String realUploadPath, String imgPath) {  
         /** 
          * 讀取二維碼圖片,並構建繪圖對象 
          */  
         OutputStream os = null ;
         String logoFileName = "logo_"+imgPath ;  
        try {
            Image image2 = ImageIO.read(image) ;
            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(new File(realUploadPath+"/"+"logo.jpg"));
             //開始繪製圖片  
             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(realUploadPath+"/"+logoFileName) ;
                JPEGImageEncoder en = JPEGCodec.createJPEGEncoder(os) ;
                en.encode(bufferImage) ;

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if(os!=null) {
                try {
                    os.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }   
         return uploadPath+"/"+logoFileName ;  
     }  
}

解碼
ZxingDecoderService .java

package com.wenteryan.service;

import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import org.springframework.stereotype.Service;

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;

@Service
public class ZxingDecoderService {

    public String zxingdecode(String realImgPath) {
        BufferedImage image = null;  
        Result result = null;  
        try {  
            image = ImageIO.read(new File(realImgPath));  
            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<DecodeHintType, Object>();  
            hints.put(DecodeHintType.CHARACTER_SET, "utf-8");  

            result = new MultiFormatReader().decode(bitmap, hints);  
            return result.getText();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return result.getText() ;
    }
}

2.寫實現類

package com.wenteryan.action;

import java.io.File;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.servlet.ModelAndView;

import com.wenteryan.service.CoderService;
import com.wenteryan.service.LogoConfig;
import com.wenteryan.service.ZxingDecoderService;

@Controller
public class ZxingEncoderAction {

    private LogoConfig logiconfig ;
    private ZxingDecoderService zxingDecodeService ;
    private CoderService coderService ;

    @RequestMapping(value="/zxingdecode", method=RequestMethod.GET)
    public ModelAndView zxingdecode(@RequestParam("realImgPath") String realImgPath, HttpSession session) {
        String uploadPath = "/images" ;
        String realUploadPath = session.getServletContext().getRealPath(uploadPath) ;
        String imgPath = realUploadPath+"/"+realImgPath ;
        String result = zxingDecodeService.zxingdecode(imgPath) ;

        ModelAndView ret = new ModelAndView() ;
        ret.addObject("result", result) ;
        ret.setViewName("zxingdecode");

        return ret ;
    }


    @RequestMapping(value="/zxingcoder", method=RequestMethod.GET)
    public ModelAndView watermark(HttpSession session) throws Exception {
        String uploadPath = "/images" ;
        String realUploadPath = session.getServletContext().getRealPath(uploadPath) ;
        String imageName = "12345"+".png" ;
        // 模擬訂單詳情
        String contents = "訂單編號:20160512082345"+"\n"+"訂單金額:¥ 2050.00"+"\n"+"支付方式:預存款"+"\n"+"配送方式:京東快遞" ;  

        int width = 300;  
        int height = 300; 
        String zxingImage = coderService.encode(contents, width, height, uploadPath, realUploadPath, imageName);  

        File image = new File(realUploadPath+"/"+imageName); 
        String logoImageUrl = logiconfig.LogoMatrix(image, uploadPath, realUploadPath, imageName) ;

        ModelAndView ret = new ModelAndView() ;
        ret.addObject("imageUrl", zxingImage) ;
        ret.addObject("imageName", imageName) ;
        ret.addObject("logoImageUrl", logoImageUrl) ;
        ret.setViewName("zxingcoder");

        return ret ;
    }

    @Autowired
    public void setLogiconfig(LogoConfig logiconfig) {
        this.logiconfig = logiconfig;
    }

    @Autowired
    public void setZxingDecodeService(ZxingDecoderService zxingDecodeService) {
        this.zxingDecodeService = zxingDecodeService;
    }

    @Autowired
    public void setCoderService(CoderService coderService) {
        this.coderService = coderService;
    }  

}

3. 編寫頁面

index.jsp

<div class="panel-body">
        <h2>請覈對你的訂單信息</h2>
        <table class="table  table-bordered table-hover">
            <thead>
            </thead>
            <tbody>
                <tr><td>訂單編號:</td><td>20160512082345</td></tr>
                <tr><td>訂單金額:</td><td>¥ 2050.00</td></tr>
                <tr><td>支付方式:</td><td>預存款</td></tr>
                <tr><td>配送方式:</td><td>京東快遞</td></tr>
            </tbody>
          </table>
        <br>
        <a href="zxingcoder" class="btn btn-success" type="submit">如果無誤,確認提交</a>
    </div>

zxingcoder.jsp

<div class="panel-heading"><h2>二維碼與有Logo 的二維碼</h2></div>
    <div class="panel-body">
        <div class="col-md-6" align="center">
        <a href="zxingdecode?realImgPath=${imageName }">
        <img class="img-responsive img-rounded" src="${pageContext.request.contextPath}${imageUrl }"/>
        <b class="btn btn-success" >我要解碼</b>
        </a>
        </div>
        <div class="col-md-6" align="center">
        <a href="zxingdecode">
        <img class="img-responsive img-rounded" src="${pageContext.request.contextPath}${logoImageUrl }"/>
        <b class="btn btn-success" >我要解碼</b>
        </a>
        </div>
        <div class="col-md-12">
        <br>
        <a class="btn btn-warning" href="${pageContext.request.contextPath }">返回</a>
        </div>
    </div>

zxingdecode.jsp

<div class="panel-heading"><h2>二維碼解碼數據</h2></div>
    <div class="panel-body">
        <div class="col-md-12" align="center">
        <br><br>
        <p>${result }</p>
        </div>
        <div class="col-md-12">
        <br>
        <a class="btn btn-warning" href="${pageContext.request.contextPath }">返回</a>
        </div>
    </div>

總結

二維碼每個人都一定不陌生,尤其是在支付寶和微信的努力下,相信每個人都或多或少的使用過”掃一掃“,這個功能而作爲開發者,不管是練習還是研究或者是公司的項目,大家都應該有過二維碼的開發經驗。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章