二维码学习(三):使用qrcode生成与解析二维码

这篇使用qrcode生成二维码,代码如下:

package com.wjl.test;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;

import jp.sourceforge.qrcode.QRCodeDecoder;
import jp.sourceforge.qrcode.data.QRCodeImage;

import com.swetake.util.Qrcode;

/**
 * 使用qrcode生成与解析二维码
 * 两个问题:
 * 1、内容不能太多,若是太多将不能生成二维码
 * 2、没有logo的二维码可以解析,有logo的二维码解析时报错:Give up decoding
 * */
public class CreateQRCodeInqrcode {
	private static final String encode="GB2312";
	public static void main(String[] args) {
		//1、定义qrcode的版本、二维码图片后缀名和内容
		int version = 7;
		
		//png比jpg的两个优点:1、png支持透明 2、png较小
		String format = "png";
		String contents = "使用qccode生成二维码";
		System.out.println("生成二维码内容:"+contents);
		
		//2、定义二维码文件
		String filePath = "D:"+File.separator+"temp"+File.separator+"qccode"+System.currentTimeMillis()+"."+format;
		File QRFile = new File(filePath);
		
		//3、生成二维码
		CreateQRCodeInqrcode qrcode = new CreateQRCodeInqrcode();
		boolean flag = qrcode.createQRCode(contents,version,format,QRFile);
		if(flag){//说明生成二维码成功
			System.out.println("文件路径:"+filePath);
			//4、添加logo
			String logoPath = "D:"+File.separator+"temp"+File.separator+"logo.jpg";
			File logoFile = new File(logoPath);
			//为二维码添加logos(这里有一个问题:若没有LOGO可以正常解析,若有LOGO解析的时候报错:Give up decoding)
			//int resu = qrcode.addLogoQRCode(QRFile, logoFile, format,2);
			
			//5、解析二维码
			String result = qrcode.readQRCode(QRFile);
			System.out.println("解析二维码内容:"+result);
		}
	}
	
	/**
	 * 该方法用来生成二维码
	 * @param contents:二维码内容
	 * @param width:二维码宽度
	 * @param version:版本
	 * @param format:二维码图片后缀名
	 * @param QRFile:二维码图片文件
	 * @return boolean:true-生成成功 false-生成失败
	 * */
	public boolean createQRCode(String contents,int version,String format,File QRFile){
		boolean result = false;
		try{
			Qrcode x = new Qrcode();
			x.setQrcodeErrorCorrect('M');//纠错等级
			x.setQrcodeEncodeMode('B');//N代表数字 A代表z-Z,B代表其他字符
			// 设置设置二维码尺寸,取值范围1-40,值越大尺寸越大,可存储的信息越大 
			x.setQrcodeVersion(version);
			
			int width = 67+12*(version-1);
			int height = width;
			BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
			Graphics2D gs = bufferedImage.createGraphics();
			gs.setBackground(Color.WHITE);//背景色
			gs.setColor(Color.BLACK);
			gs.clearRect(0, 0, width, height);//清除画板内容
			
			int pixoff = 2;//偏移量(若没有偏移量,可能会导致解析出错)
			//将内容转成字节数
			byte[] data = contents.getBytes(encode);
			if(data.length>0 && data.length<120){
				boolean[][] s = x.calQrcode(data);
				for(int i=0;i<s.length;i++){
					for(int j=0;j<s.length;j++){
						if(s[j][i]){
							//填充画板
							gs.fillRect(j*3+pixoff, i*3+pixoff, 3, 3);
						}
					}
				}
			}
			gs.dispose();
			bufferedImage.flush();
			
			ImageIO.write(bufferedImage, format, QRFile);
			result = true;
		}catch(Exception e){
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 该方法用来读取二维码内容
	 * @param QRFile:二维码图片文件
	 * @return String:二维码内容 
	 * **/
	public String readQRCode(File QRFile){
		if(!QRFile.exists() || !QRFile.isFile()) return "";
		String result="";
		try{
			BufferedImage bufferedImage2 = ImageIO.read(QRFile);
			QRCodeDecoder codeDecoder = new QRCodeDecoder();
			byte[] re = codeDecoder.decode(new MyQRCodeImage(bufferedImage2));
			result = new String(re,encode);
		}catch(Exception e){
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 给二维码图片添加Logo
	 * @param QRFile:二维码图片文件
	 * @param logoFile:logo文件对象
	 * @param format:添加logo后的二维码文件后缀名
	 * @param logoConfig:logo设置
	 * @param postion:1-右下角 非1-中间
	 * @return int:1-找不到二维码文件或logo文件 2-生成成抛出异常 3-生成成功
	 */
	public int addLogoQRCode(File QRFile,File logoFile,String format,int position) {
		int result = 3;
		try {
			//二维码文件或logo文件不存在或不是文件
			if (!QRFile.exists() || !QRFile.isFile() || !logoFile.exists() || !logoFile.isFile()) {
				return 1;
			}
			
			//读取二维码图片,并构建绘图对象
			BufferedImage image = ImageIO.read(QRFile);
			Graphics2D g = image.createGraphics();

			//读取Logo图片
			BufferedImage logo = ImageIO.read(logoFile);
			//设置logo的大小,此处设置为二维码图片的20%,因为过大会盖掉二维码
			int widthLogo = logo.getWidth(null) > image.getWidth() * 2 / 10 ? (image
					.getWidth() * 2 / 10) : logo.getWidth(null), heightLogo = logo
					.getHeight(null) > image.getHeight() * 2 / 10 ? (image
					.getHeight() * 2 / 10) : logo.getWidth(null);

			// 计算图片放置位置
			int x=0,y=0;
			if(position==1){//logo放在右下角
				x = (image.getWidth() - widthLogo);
				y = (image.getHeight() - heightLogo);
			}else{//logo放在中心
				x = (image.getWidth() - widthLogo) / 2; 
				y =(image.getHeight() - heightLogo) / 2;
			}
			
			// 开始绘制图片
			g.drawImage(logo, x, y, widthLogo, heightLogo, null);
			g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
			g.setStroke(new BasicStroke(2));
			g.drawRect(x, y, widthLogo, heightLogo);

			g.dispose();
			logo.flush();
			image.flush();

			ImageIO.write(image,format,QRFile);
		} catch (Exception e) {
			result = 2;
			e.printStackTrace();
		}
		return result;
	}
		
}

class MyQRCodeImage implements QRCodeImage{

	BufferedImage bufferedImage;
	public MyQRCodeImage(BufferedImage bufferedImage){
		this.bufferedImage = bufferedImage;
	}
	public int getHeight() {
		return bufferedImage.getHeight();
	}

	public int getPixel(int arg0, int arg1) {
		return bufferedImage.getRGB(arg0, arg1);
	}

	public int getWidth() {
		return bufferedImage.getWidth();
	}
}

需要的jar包:

qrcode.jar:用来生成二维码

Qrcode_swetake.jar:用来解析二维码

猜你喜欢

转载自1017401036.iteye.com/blog/2316962