巴拉巴拉
小魔仙

JavaWeb生成简单二维码

当根据需要,我们需要在页面上生成动态可变的二维码的时候,可以根据本例做为参考,本例使用Servlet做范例,使用的是Google的zxing二维码工具。

zxing-core-3.2.2.jar

更新代码:2016-10-19

1.重构了重载

2.现在二维码是彩色的!

首先,我们需要写两个工具类,外加一个Servlet,总共三个类。

第一个:BufferedImageLuminanceSource.java

package com.againfly.qrcode;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;

import com.google.zxing.LuminanceSource;

public class BufferedImageLuminanceSource extends LuminanceSource {
    private final BufferedImage image;
    private final int left;
    private final int top;

    public BufferedImageLuminanceSource(BufferedImage image) {
        this(image, 0, 0, image.getWidth(), image.getHeight());
    }

    public BufferedImageLuminanceSource(BufferedImage image, int left,
            int top, int width, int height) {
        super(width, height);

        int sourceWidth = image.getWidth();
        int sourceHeight = image.getHeight();
        if (left + width > sourceWidth || top + height > sourceHeight) {
            throw new IllegalArgumentException(
                    "Crop rectangle does not fit within image data.");
        }

        for (int y = top; y < top + height; y++) {
            for (int x = left; x < left + width; x++) {
                if ((image.getRGB(x, y) & 0xFF000000) == 0) {
                    image.setRGB(x, y, 0xFFFFFFFF); // = white
                }
            }
        }

        this.image = new BufferedImage(sourceWidth, sourceHeight,
                BufferedImage.TYPE_BYTE_GRAY);
        this.image.getGraphics().drawImage(image, 0, 0, null);
        this.left = left;
        this.top = top;
    }

   
    public byte[] getRow(int y, byte[] row) {
        if (y < 0 || y >= getHeight()) {
            throw new IllegalArgumentException(
                    "Requested row is outside the image: " + y);
        }
        int width = getWidth();
        if (row == null || row.length < width) {
            row = new byte[width];
        }
        image.getRaster().getDataElements(left, top + y, width, 1, row);
        return row;
    }

   
    public byte[] getMatrix() {
        int width = getWidth();
        int height = getHeight();
        int area = width * height;
        byte[] matrix = new byte[area];
        image.getRaster().getDataElements(left, top, width, height, matrix);
        return matrix;
    }

   
    public boolean isCropSupported() {
        return true;
    }

   
    public LuminanceSource crop(int left, int top, int width, int height) {
        return new BufferedImageLuminanceSource(image, this.left + left,
                this.top + top, width, height);
    }

   
    public boolean isRotateSupported() {
        return true;
    }

   
    public LuminanceSource rotateCounterClockwise() {
        int sourceWidth = image.getWidth();
        int sourceHeight = image.getHeight();
        AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0,
                0.0, 0.0, sourceWidth);
        BufferedImage rotatedImage = new BufferedImage(sourceHeight,
                sourceWidth, BufferedImage.TYPE_BYTE_GRAY);
        Graphics2D g = rotatedImage.createGraphics();
        g.drawImage(image, transform, null);
        g.dispose();
        int width = getWidth();
        return new BufferedImageLuminanceSource(rotatedImage, top,
                sourceWidth - (left + width), getHeight(), width);
    }
}

第二个:QRCodeUtil.java

package com.againfly.qrcode;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Shape;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

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 QRCodeUtil {
    
    public static void main(String[] args) throws IOException {
        String charset = "utf-8";
        String text = "http://www.againfly.com/";
        String insertImg = "D://q.png";
        BufferedImage qr = null;
        try {
            QRCodeUtil.CHARSET = charset;
            qr = QRCodeUtil.createImage(text, 300, insertImg, 62);
        } catch (Exception e) {
            e.printStackTrace();
        }
        ImageIO.write(qr, "png", new File("D://q.jpg"));
    }
 
    private static String CHARSET = "utf-8";
    // 二维码尺寸
    private static final int QRCODE_SIZE = 300;
    
    public static BufferedImage createImage(String content) throws Exception{
        return createImage(content, "");
    }
    
    public static BufferedImage createImage(String content, String logoPath) throws Exception{
        File logoFile = new File(logoPath);
        return createImage(content, QRCODE_SIZE, logoFile);
    }
    
    public static BufferedImage createImage(String content, File logoFile) throws Exception{
        return createImage(content, QRCODE_SIZE, logoFile);
    }
    
    public static BufferedImage createImage(String content, int size, File logoFile) throws Exception{
        return createImage(content, size, logoFile, (int)(size / 5));
    }
    
    public static BufferedImage createImage(String content, int size, String logoPath, int logoSize) 
            throws Exception {
        return createImage(content, size, new File(logoPath), logoSize);
    }
 
    public static BufferedImage createImage(String content, int size, File logoFile, int logoSize) 
            throws Exception {
        Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
        hints.put(EncodeHintType.MARGIN, 1);
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
                BarcodeFormat.QR_CODE, size, size, hints);
        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                //自定义二维码颜色和背景颜色
                int num1 = (int) (50 - (50.0 - 13.0) / bitMatrix.getHeight() * (y + 1));
                int num2 = (int) (165 - (165.0 - 72.0) / bitMatrix.getHeight() * (y + 1));
                int num3 = (int) (162 - (162.0 - 107.0) / bitMatrix.getHeight() * (y + 1));
                Color color = new Color(num1, num2, num3);
                int colorInt = color.getRGB();
                //image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
                image.setRGB(x, y, bitMatrix.get(x, y) ? colorInt : 0xFFFFFFFF);
            }
        }
        // 插入logo图片
        if (null != logoFile) {
            QRCodeUtil.insertImage(image, size, logoFile, logoSize);
        }
        return image;
    }
 
    private static void insertImage(BufferedImage source, int size, File logoFile, int logoSize)
            throws Exception {
        if (!logoFile.exists()) {
            System.err.println("" + logoFile +"   该文件不存在!");
            return;
        }
        Image src = ImageIO.read(logoFile);
        int width = src.getWidth(null);
        int height = src.getHeight(null);
        { // 压缩LOGO
            if (width > logoSize) {
                width = logoSize;
            }
            if (height > logoSize) {
                height = logoSize;
            }
            Image image = src.getScaledInstance(width, height,
                    Image.SCALE_SMOOTH);
            BufferedImage tag = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
            Graphics g = tag.getGraphics();
            g.drawImage(image, 0, 0, null); // 绘制缩小后的图
            g.dispose();
            src = image;
        }
        Graphics2D graph = source.createGraphics();// 插入LOGO
        int x = (size - width) / 2;
        int y = (size - height) / 2;
        graph.drawImage(src, x, y, width, height, null);
        Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
        graph.setStroke(new BasicStroke(3f));
        graph.draw(shape);
        graph.dispose();
    }
}

第三个Servlet:QRDemo.java

package com.againfly.demo;

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.againfly.qrcode.QRCodeUtil;

public class QRDemo extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("image/png");
        response.setHeader("Pragma", "no-cache");//禁止图像缓存。
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        String formatName = "PNG";
        String charset = "utf-8";
        String text = "http://www.againfly.com";
        String insertImg = "/MYOTee.JPG";
        BufferedImage qr = null;
        try {
            qr = QRCodeUtil.createImage(text, insertImg);
        } catch (Exception e) {
            e.printStackTrace();
        }
        ImageIO.write(qr, formatName, response.getOutputStream());
    }
}

////////////////////////////////////////////_/

这是彩色的图:

qr_colorful

效果图:

20160427093525

 

2016-10-19

补充内容:从webroot下获取File文件

public static File getRootFile(String src) {
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    if (classLoader == null) {
        classLoader = ClassLoader.getSystemClassLoader();
    }
    java.net.URL url = classLoader.getResource("");
    String ROOT_CLASS_PATH = url.getPath() + "/";
    File rootFile = new File(ROOT_CLASS_PATH);
    String WEB_INFO_DIRECTORY_PATH = rootFile.getParent() + "/";
    File webInfoDir = new File(WEB_INFO_DIRECTORY_PATH);
    String SERVLET_CONTEXT_PATH = webInfoDir.getParent() + "/";

    // 这里 SERVLET_CONTEXT_PATH 就是WebRoot的路径
    String path = SERVLET_CONTEXT_PATH + "/" + src;
    path = path.replaceAll("%20", " ");
    return new File(path);
}

 

赞(0) 打赏
如果文章对你有帮助,欢迎你来评价反馈。AgainFly » JavaWeb生成简单二维码
标签:

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  • Q Q(选填)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏