JAVA 使用com.google.zxing包生成二维码

公司需求:不同的产品生成不同的二位码,微信扫描二维码后跳转到对应的公众号中查看详情。

1.首先使用com.google.zxing包

       
            com.google.zxing
            core
            3.0.0
        

2.代码中使用

QRCodeUtil.encode(url, picAddress, folder, comprass,title,qrCodeWords);

url:二维码的内容

picAddress:嵌入在二维码中的图片地址

folder:二维码存储路径

comprass:是否压缩

title:二维码文件名称

qrCodeWords:二维码下方文字内容

3.相关类:

import java.awt.BasicStroke;
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.OutputStream;
import java.util.Hashtable;
import java.util.Random;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Result;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class QRCodeUtil {
	 private static final String CHARSET = "utf-8";
	   // private static final String FORMAT_NAME = "JPG";
	    private static final String FORMAT_NAME = "PNG";
	    // 二维码尺寸
	    private static final int QRCODE_SIZE = 300;
	    // LOGO宽度
	    private static final int WIDTH = 60;
	    // LOGO高度
	    private static final int HEIGHT = 60;
	    
	    @SuppressWarnings({ "rawtypes", "unchecked" })
	    private static BufferedImage createImage(String content, String imgPath,
	            boolean needCompress) throws Exception {
			Hashtable hints = new Hashtable();
	        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
	        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
	        hints.put(EncodeHintType.MARGIN, 1);
	        BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
	                BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_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++) {
	                image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000
	                        : 0xFFFFFFFF);
	            }
	        }
	        if (imgPath == null || "".equals(imgPath)) {
	            return image;
	        }
	        // 插入图片
	        QRCodeUtil.insertImage(image, imgPath, needCompress);
	        return image;
	    }
	    private static void insertImage(BufferedImage source, String imgPath,
	            boolean needCompress) throws Exception {
	        File file = new File(imgPath);
	        if (!file.exists()) {
	            System.err.println(""+imgPath+"   该文件不存在!");
	            return;
	        }
	        Image src = ImageIO.read(new File(imgPath));
	        int width = src.getWidth(null);
	        int height = src.getHeight(null);
	        if (needCompress) { // 压缩LOGO
	            if (width > WIDTH) {
	                width = WIDTH;
	            }
	            if (height > HEIGHT) {
	                height = HEIGHT;
	            }
	            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;
	        }
	        // 插入LOGO
	        Graphics2D graph = source.createGraphics();
	        int x = (QRCODE_SIZE - width) / 2;
	        int y = (QRCODE_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();
	    }
	    public static void encode(String content, String imgPath, String destPath,
	            boolean needCompress) throws Exception {
	        BufferedImage image = QRCodeUtil.createImage(content, imgPath,
	                needCompress);
	        mkdirs(destPath);
	        String file = new Random().nextInt(99999999)+".jpg";
	        ImageIO.write(image, FORMAT_NAME, new File(destPath+"/"+file));
	    }
	    public static void mkdirs(String destPath) {
	        File file =new File(destPath);   
	        //当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
	        if (!file.exists() && !file.isDirectory()) {
	            file.mkdirs();
	        }
	    }
	    public static void encode(String content, String imgPath, String destPath)
	            throws Exception {
	        QRCodeUtil.encode(content, imgPath, destPath, false);
	    }

	   
	    public static void encode(String content, String destPath,
	            boolean needCompress) throws Exception {
	        QRCodeUtil.encode(content, null, destPath, needCompress);
	    }

	   
	    public static void encode(String content, String destPath) throws Exception {
	        QRCodeUtil.encode(content, null, destPath, false);
	    }

	   
	    public static void encode(String content, String imgPath,
	            OutputStream output, boolean needCompress) throws Exception {
	        BufferedImage image = QRCodeUtil.createImage(content, imgPath,
	                needCompress);
	        ImageIO.write(image, FORMAT_NAME, output);
	    }

	   
	    public static void encode(String content, OutputStream output)
	            throws Exception {
	        QRCodeUtil.encode(content, null, output, false);
	    }

	   
	    @SuppressWarnings({ "rawtypes", "unchecked" })
		public static String decode(File file) throws Exception {
	        BufferedImage image;
	        image = ImageIO.read(file);
	        if (image == null) {
	            return null;
	        }
	        BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(
	                image);
	        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
	        Result result;
	        Hashtable hints = new Hashtable();
	        hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
	        result = new MultiFormatReader().decode(bitmap, hints);
	        String resultStr = result.getText();
	        return resultStr;
	    }

	   
	    public static String decode(String path) throws Exception {
	        return QRCodeUtil.decode(new File(path));
	    }
	    
	    public static void encode(String content, String imgPath, String destPath,
	            boolean needCompress,String paperId) throws Exception {
	        BufferedImage image = QRCodeUtil.createImage(content, imgPath,
	                needCompress);
	        mkdirs(destPath);
	        String file = paperId+".png";
	        ImageIO.write(image, FORMAT_NAME, new File(destPath+"/"+file));
	    }
	    public static String encode(String content, String imgPath, String destPath, String bottomWords,
	            boolean needCompress) throws Exception {
	        BufferedImage image = QRCodeUtil.createImage(content, imgPath,
	                needCompress);
	        image=WriteWordsBottomQrCode.insertWords(image,bottomWords);
	   	 
            image.flush();
	        mkdirs(destPath);
	        String file = new Random().nextInt(99999999)+".jpg";
	        ImageIO.write(image, FORMAT_NAME, new File(destPath+"/"+file));
	        return destPath+"/"+file;
	    }
	    
	    public static void encode(String content, String imgPath, String destPath,
	            boolean needCompress,String paperId,String bottomContent) throws Exception {
	        BufferedImage image = QRCodeUtil.createImage(content, imgPath,
	                needCompress);
	        if(bottomContent != null && bottomContent.length() > 0) {
	        	image=WriteWordsBottomQrCode.insertWords(image,bottomContent);
	        }
	        mkdirs(destPath);
	        String file = paperId+".png";
	        ImageIO.write(image, FORMAT_NAME, new File(destPath+"/"+file));
	    }
	    
	    public static void main(String[] args) throws Exception {
	        String text = "http://www.cnblogs.com/klslb/";//二维码的链接地址
	        //String path = new QRCodeUtil().getClass().getClassLoader().getResource("image/qrLogo.jpg").getPath();
	        QRCodeUtil.encode(text, "d:/QRCodeDoc/qrLogo.jpg", "d:/QRCodeDoc", true);
	    }
}
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;
	}

	@Override
	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;
	}

	@Override
	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 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);
	}
}
import com.google.zxing.common.BitMatrix;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

/**
 * 
 * Created by Binary Wang on 2017-01-05.
 * @author binarywang(Binary Wang)
 * 
*/ public final class MatrixToImageWriter { private static final int BLACK = 0xFF000000; private static final int WHITE = 0xFFFFFFFF; private MatrixToImageWriter() { } private static BufferedImage toBufferedImage(BitMatrix matrix) { int width = matrix.getWidth(); int height = matrix.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++) { image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE); } } return image; } public static void writeToFile(BitMatrix matrix, String format, File file) throws IOException { BufferedImage image = toBufferedImage(matrix); if (!ImageIO.write(image, format, file)) { throw new IOException("Could not write an image of format " + format + " to " + file); } } public static void writeToStream(BitMatrix matrix, String format, OutputStream stream) throws IOException { BufferedImage image = toBufferedImage(matrix); if (!ImageIO.write(image, format, stream)) { throw new IOException("Could not write an image of format " + format); } } }
import java.awt.*;
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 org.apache.commons.lang3.StringUtils;


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 WriteWordsBottomQrCode {
	private static final int QRCOLOR = 0xFF000000; // 二维码颜色 默认是黑色
	   private static final int BGWHITE = 0xFFFFFFFF; // 背景颜色
	 
	   private static final int WIDTH = 300; // 二维码宽
	   private static final int HEIGHT = 300; // 二维码高
	 
	   private static final int WORDHEIGHT = 345; // 加文字二维码高
	 
	 
	   /**
	    * 用于设置QR二维码参数
	    */
	   private static Map hints = new HashMap() {
	      private static final long serialVersionUID = 1L;
	      {
	         // 设置QR二维码的纠错级别(H为最高级别)具体级别信息
	         put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
	         // 设置编码方式
	         put(EncodeHintType.CHARACTER_SET, "utf-8");
	         put(EncodeHintType.MARGIN, 0);
	      }
	   };
	 
	 
	   /**
	    * 设置 Graphics2D 属性  (抗锯齿)
	    * @param graphics2D
	    */
	   private static void setGraphics2D(Graphics2D graphics2D){
	      graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
	      graphics2D.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
	      Stroke s = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER);
	      graphics2D.setStroke(s);
	   }
	 
	 
	   /**
	    * 生成二维码图片存储到filePath中
	    * 
	    * @param content
	    *            二维码内容
	    * @param filePath
	    *            成二维码图片保存路径
	    * @return
	    */
	   public static boolean createImg(String content, String filePath) {
	      boolean flag = false;
	      try {
	         MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
	         BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
	 
	         // 图片输出路径
	         String code = content.split("=")[1]; // 设备编号
	 
	         File file = new File(filePath + "//PSD" + code + ".jpg");
	         if (!file.exists()) {
	            // 如果文件夹不存在则创建
	            file.mkdirs();
	         }
	 
	         // 输出二维码图片到文件夹
	         MatrixToImageWriter.writeToFile(bitMatrix, "jpg", file);
	         flag = true;
	 
	      } catch (IOException e) {
	         e.printStackTrace();
	      } catch (Exception e) {
	         e.printStackTrace();
	      }
	      return flag;
	   }
	 
	 
	   /**
	    * 把带logo的二维码下面加上文字
	    * @param image
	    * @param words
	    * @return
	    */
	   public static BufferedImage insertWords(BufferedImage image,String words){
	      // 新的图片,把带logo的二维码下面加上文字
	      if (StringUtils.isNotEmpty(words)) {
	 
	         //创建一个带透明色的BufferedImage对象
	         BufferedImage outImage = new BufferedImage(WIDTH, WORDHEIGHT, BufferedImage.TYPE_INT_ARGB);
	         Graphics2D outg = outImage.createGraphics();
	         setGraphics2D(outg);
	 
	         // 画二维码到新的面板
	         outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
	         // 画文字到新的面板
	         Color color=new Color(0,0,0);
	         outg.setColor(color);
	         // 字体、字型、字号
	         if(words != null && words.length() > 8) {
	        	 outg.setFont(new Font("微软雅黑", Font.PLAIN, 25));
	         } else {
	        	 outg.setFont(new Font("微软雅黑", Font.PLAIN, 30));
	         }
	         
	         //文字长度
	         int strWidth = outg.getFontMetrics().stringWidth(words);
	         //总长度减去文字长度的一半  (居中显示)
	         int wordStartX=(WIDTH - strWidth) / 2;
	         //height + (outImage.getHeight() - height) / 2 + 12
	         int wordStartY=HEIGHT+30;
	         // 画文字
	         outg.drawString(words, wordStartX, wordStartY);
	         outg.dispose();
	         outImage.flush();
	         return outImage;
	      }
	      return null;
	   }
	 
	 
	   /**
	    * @description 生成带logo的二维码图片 二维码下面带文字
	    * @param logoFile loge图片的路径
	    * @param bgFile 背景图片的路径
	    * @param codeFile 图片输出路径
	    * @param qrUrl 二维码内容
	    * @param words 二维码下面的文字
	    */
	   public static void drawLogoQRCode(File logoFile,File bgFile, File codeFile, String qrUrl, String words) {
	        try {
	            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
	            // 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数
	            BitMatrix bm = multiFormatWriter.encode(qrUrl, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
	            BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
	 
	            // 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
	            for (int x = 0; x < WIDTH; x++) {
	                for (int y = 0; y < HEIGHT; y++) {
	                    image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);
	                }
	            }
	 
	            //把logo画到二维码上面
	            if (logoFile != null && logoFile.exists()) {
	                // 构建绘图对象
	                Graphics2D g = image.createGraphics();
	            setGraphics2D(g);
	                // 读取Logo图片
	                BufferedImage logo = ImageIO.read(logoFile);
	                // 开始绘制logo图片 等比缩放:(width * 2 / 10 height * 2 / 10)不需缩放直接使用图片宽高
	            //width * 2 / 5 height * 2 / 5  logo绘制在中心点位置
	                g.drawImage(logo, WIDTH * 2 / 5, HEIGHT * 2 / 5, logo.getWidth(), logo.getHeight(), null);
	                g.dispose();
	                logo.flush();
	            }
	 
	            // 新的图片,把带logo的二维码下面加上文字
	            image=insertWords(image,words);
	 
	            image.flush();
	            ImageIO.write(image, "png", codeFile);
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	   }
	   
	   public static void main(String[] args) {
	      //logo
	      File logoFile = new File("d:/QRCodeDoc/qrLogo.jpg");
	      //背景图片
	     // File bgFile = new File("G://picture/01.png");
	      //生成图片
	        File qrCodeFile = new File("d:/QRCodeDoc/qrLogo111.jpg");
	        //二维码内容
	        String url = "https://w.url.cn/s/AYmfAV3";
	        //二维码下面的文字
	        String words = "PSD000001";
	        drawLogoQRCode(logoFile,null, qrCodeFile, url, words);
	   }
	
}

以上代码即可完成生成二维码功能!

生成二维码如下:

JAVA 使用com.google.zxing包生成二维码_第1张图片

代码来源于网上,本人只使用了具体功能完成了自己的业务

你可能感兴趣的:(二维码,java)