二维码(带Logo)加密解密-QRCode方式

学习总结记录 同时被 2 个专栏收录
11 篇文章 0 订阅
5 篇文章 0 订阅

二维码加密解密-QRCode

QRCode生成和解析二维码的流程步骤在代码里面方便理解。

加密工具类

/**  
 * Copyright © 2020wangylCompany. All rights reserved.
 *
 * @Title: QRCodeUtil.java
 * @Prject: MyTestDemo
 * @Package: qrcode
 * @Description: TODO
 * @version: V1.0  
 */

package qrcode;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import javax.imageio.ImageIO;

import com.swetake.util.Qrcode;

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



public class QRCodeUtil {
	 //加密:文字信息----------》二维码
	/**
	 * 
	 * @Title: encoderQRCode
	 * @Description: TODO
	 * @param content	二维码的内容
	 * @param imgPath	二维码的生成路径	src/二维码.png
	 * @param imgType	二维码的图片格式	png
	 * @param size		二维码的边长(二维码是正方形,所以只需要边长尺寸即可)
	 * @return: void	由于二维码生成就是二维码直接输出了,可以不用返回值,或者可以添加boolean返回值
	     
	     
	     这里暂时不处理异常,主要生成二维码
	 
	 * @throws IOException 
	 */
	
	public void encoderQRCode(String content,String imgPath,String imgType,int size) throws IOException{
		/**
		 * API
		 * 生成图片需要依赖 ImageIO 里面的  write 方法
		 * ImageIO.write(im, formatName, output)
		 * im			RenderedImage
		 * formatName	格式名字
		 * output		文件类型,所以需要与现有文件
		 * 
		 * 
		 * RenderedImage 是个接口,不能直接new对象,只能通过他的实现类BufferedImage来简历对象
		 * (ctrl + t  选中RenderedImage,可以看到关系里面有BufferedImage是RenderedImage的一个实现类)
		 * BufferedImage类型可以代表内存中的一张图片,内存中产生图片以后直接输出到硬盘即可
		 * 所以现在需要在内存中产生一张图片,由于产生过程相对比较复杂,这里单独创建一个方法qRCodeCommon()来产生img对象
		 *qRCodeCommon()用来产生图片,返回值必定是BufferedImage类型
		 *
		 */
//		RenderedImage
//		BufferedImage bufImg = qRCodeCommon(content,imgType,size);//二维码生成版(初始版本)
		BufferedImage bufImg = qRCodeCommon2(content,imgType,size);//二维码生成版(加logo)
		File file = new File(imgPath);
		ImageIO.write(bufImg, imgType, file);
		
	}


	/**
	 * 
	 * @Title: qRCodeCommon
	 * @Description: TODO	二维码生成版(初始版本)
	 * @param content	二维码中的隐藏信息类容
	 * @param imgType	图片的格式		png
	 * @param size		二维码的尺寸	边长
	 * @return			返回生成的图片对象
	 * @return: BufferedImage
	 
	 * @throws UnsupportedEncodingException 
	 */
	private BufferedImage qRCodeCommon(String content,String imgType,int size) throws UnsupportedEncodingException {
		//代码顺序调整前,注释未变化--------------------------------------------
//		BufferedImage bufImg =null;
//		/**
//		 * BufferedImage	内存中的图片
//		 * 正常情况需要对象直接new 就可以,但是bufImg = new BufferedImage()不可以,说明这个class没有无参构造
//		 * 查看源码,发现没有无参构造但是有有参构造,选择合适的有参构造
//		 * new BufferedImage(width, height, imageType)
//		 * width		int		size
//		 * height		int		size
//		 * imageType	int		BufferedImage.TYPE_INT_RGB
//		 * 
//		 * imageType 这里或者直接写1
//		 * 美术的三原色是 红、黄、蓝 ,计算机的三原色是 red green blue 简称RGB
//		 * 
//		 * 
//		 */
//		bufImg = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
//		//有了图片对象后,在通过图片对象生成一个画板
//		Graphics2D graphics2d = bufImg.createGraphics();
//		//设置画板的背景色设置为白色
//		graphics2d.setBackground(Color.WHITE);
//		/**
//		 * graphics2d.clearRect(x, y, width, height);
//		 * x、y		坐标位置,0,0就是从画板的 左上角 开始
//		 * width	二维码的边长就是画板的边长
//		 * height	二维码的边长就是画板的边长
//		 */
//		graphics2d.clearRect(0, 0, size, size);//初始化画板
//		/**
//		 * 画板的背景色设置好了,画板的大小设置好了,现在开始准备画画了(画二维码)
//		 */
//		graphics2d.setColor(Color.BLACK);//设置二维码的颜色:这里设置黑色
//		/**
//		 * 剩下的就是开始话二维码
//		 * 二维码是如何画的?
//		 * 这里简述方便理解:
//		 * 		helloworld是需要转换成二维码的隐藏信息,这里将helloworld转换成二位码的像素点
//		 * 这里具体是将helloworld隐藏信息转换成了boolean数组,转换成了boolean[][]二维数组
//		 * 二维码可以是一个平面,可以看成是一个二维数组,helloworld转换的过程中,对于在映射的过程中,
//		 * 某一个点如果满足映射标记为黑色,从而整体生成了一个二维码
//		 */
//		/**
//		 * 这里需要将传进来的字符串转化成一个二位数组boolean[][]
//		 * 
//		 * 转换成二位数组的话有需要一个Qrcode对象,这里是作为一个处理器
//		 * 
//		 * qrCodeHandler这里是作为一个处理器
//		 */
//		Qrcode qrCodeHandler = new Qrcode();
//		/**
//		 * 设置二维码的排错率。L/M/Q/H 从小到大
//		 * L	7%
//		 * M
//		 * Q
//		 * H	30%
//		 * 
//		 * 排错率越高,二维码可存储的信息越少,但是对二维码清晰度要求越小(容易扫出来)
//		 * 
//		 * 这里设置一个中间值 M
//		 */
//		qrCodeHandler.setQrcodeErrorCorrect('M');
//		/**
//		 * 二维码可以存放的信息类型 		N
//		 * N	数字(只能放数字)
//		 * A	数字+A~Z
//		 * B	所有
//		 * (一般都选B)
//		 */
//		qrCodeHandler.setQrcodeEncodeMode('B');
//		/**
//		 * 二维码的尺寸
//		 * 取值范围:1~40		数字越大二维码越大
//		 * 由于我们制定了二维码的尺寸,但是这里的尺寸只能是1~40,所以超出的话会出错
//		 * 但是如果真的使用40的话,那二维码又太小了
//		 * 所以这里为了保证这里满足需求(1~40),又能保证后面的不至于二维码太小,这里自定义一个公式:
//		 * 在满足qrCodeHandler.setQrcodeVersion(size);的情况下,
//		 * 再将size进行放大满足其他尺寸的需求,所以这部分代码我们要上移,
//		 * 先定义这里的尺寸,再将放大后的尺寸提供其他位置使用
//		 */
//		qrCodeHandler.setQrcodeVersion(size);
//	
//==========================================================================================		
		
		//代码顺序调整后,注释未变化--------------------------------------------
		/**
		 * 剩下的就是开始话二维码
		 * 二维码是如何画的?
		 * 这里简述方便理解:
		 * 		helloworld是需要转换成二维码的隐藏信息,这里将helloworld转换成二位码的像素点
		 * 这里具体是将helloworld隐藏信息转换成了boolean数组,转换成了boolean[][]二维数组
		 * 二维码可以是一个平面,可以看成是一个二维数组,helloworld转换的过程中,对于在映射的过程中,
		 * 某一个点如果满足映射标记为黑色,从而整体生成了一个二维码
		 */
		/**
		 * 这里需要将传进来的字符串转化成一个二位数组boolean[][]
		 * 
		 * 转换成二位数组的话有需要一个Qrcode对象,这里是作为一个处理器
		 * 
		 * qrCodeHandler这里是作为一个处理器
		 */
		Qrcode qrCodeHandler = new Qrcode();
		/**
		 * 设置二维码的排错率。L/M/Q/H 从小到大
		 * L	7%
		 * M
		 * Q
		 * H	30%
		 * 
		 * 排错率越高,二维码可存储的信息越少,但是对二维码清晰度要求越小(容易扫出来)
		 * 
		 * 这里设置一个中间值 M
		 */
		qrCodeHandler.setQrcodeErrorCorrect('M');
		/**
		 * 二维码可以存放的信息类型 		N
		 * N	数字(只能放数字)
		 * A	数字+A~Z
		 * B	所有
		 * (一般都选B)
		 */
		qrCodeHandler.setQrcodeEncodeMode('B');
		/**
		 * 二维码的尺寸
		 * 取值范围:1~40		数字越大二维码越大
		 * 由于我们制定了二维码的尺寸,但是这里的尺寸只能是1~40,所以超出的话会出错
		 * 但是如果真的使用40的话,那二维码又太小了
		 * 所以这里为了保证这里满足需求(1~40),又能保证后面的不至于二维码太小,这里自定义一个公式:
		 * 在满足qrCodeHandler.setQrcodeVersion(size);的情况下,
		 * 再将size进行放大满足其他尺寸的需求,所以这部分代码我们要上移,
		 * 先定义这里的尺寸,再将放大后的尺寸提供其他位置使用
		 */
		qrCodeHandler.setQrcodeVersion(size);
		
		/*
		 * qrCodeHandler.calQrcode(qrcodeData)
		 * calQrcode这个方法就可以将我们需要的信息编程boolean[][]
		 * 但是calQrcode(qrcodeData)的参数qrcodeData是一个字节数组类型
		 * 所以我们需要将传进来的string转换称byte[]
		 */
		byte[] contentBytes = content.getBytes("UTF-8");//将helloworld---->byte[]"helloworld"
		boolean[][] codeOut = qrCodeHandler.calQrcode(contentBytes);//获取到了二维码的二位数组
		
		//这里将size按照自定义规则放大到imgSize,然后更改后续的变量
		int imgSize = 67+12*(size-1);
		
		

		BufferedImage bufImg =null;
		/**
		 * BufferedImage	内存中的图片
		 * 正常情况需要对象直接new 就可以,但是bufImg = new BufferedImage()不可以,说明这个class没有无参构造
		 * 查看源码,发现没有无参构造但是有有参构造,选择合适的有参构造
		 * new BufferedImage(width, height, imageType)
		 * width		int		size
		 * height		int		size
		 * imageType	int		BufferedImage.TYPE_INT_RGB
		 * 
		 * imageType 这里或者直接写1
		 * 美术的三原色是 红、黄、蓝 ,计算机的三原色是 red green blue 简称RGB
		 * 
		 * 
		 */
		bufImg = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);
		//有了图片对象后,在通过图片对象生成一个画板
		Graphics2D graphics2d = bufImg.createGraphics();
		//设置画板的背景色设置为白色
		graphics2d.setBackground(Color.WHITE);
		/**
		 * graphics2d.clearRect(x, y, width, height);
		 * x、y		坐标位置,0,0就是从画板的 左上角 开始
		 * width	二维码的边长就是画板的边长
		 * height	二维码的边长就是画板的边长
		 */
		graphics2d.clearRect(0, 0, imgSize, imgSize);//初始化画板
		/**
		 * 画板的背景色设置好了,画板的大小设置好了,现在开始准备画画了(画二维码)
		 */
		graphics2d.setColor(Color.BLACK);//设置二维码的颜色:这里设置黑色
		/**
		 * 由于上面已经获取到了二维码的二位数组
		 * boolean[][] codeOut = qrCodeHandler.calQrcode(contentBytes);
		 * 所以现在只需要在画板中将二维数组画出来即可
		 * 
		 * 由于是二维数组,这里描绘二维码的时候需要对二维数组经行双循环遍历
		 * 由于已经生成了boolean[][],已经指明了元素的true和false,所以只需要对其中的元素进行判断
		 * true进行描黑,false就不管
		 */
		int pixoff = 2;//定义一个二维码偏移量,偏移一点避免顶格
		for (int i = 0; i < codeOut.length; i++) {
			for (int j = 0; j < codeOut.length; j++) {
				if (codeOut[i][j]) {//true进行描黑,false就不管
					/**
					 * graphics2d.fillRect(x, y, width, height);
					 * fillRect		填充长方形
					 * x\y		坐标(这里i是横坐标,j是纵坐标)
					 * 			由于x/y只是作标,代表的是一个点,所以一般使用x*3和y*3
					 * x*3和y*3	表示的是这个以x/y作标为起点的一个3*3的正方形
					 * width	3
					 * height	3
					 * 
					 * 由于二维码的一般是居中,所以这里需要整体给一个偏移量
					 * 所以需要提前在循环外面定义一个像素偏移量
					 * 
					 * 所以这里需要将定义好的偏移量加载坐标轴里面
					 */
					graphics2d.fillRect(i*3+pixoff, j*3+pixoff, 3, 3);
				}
			}
		}
		//操作完毕后需要释放画板空间
		graphics2d.dispose();
		//画完以后的话,流操作一般需要close或者flush一下输出出来
		//清理:管道流操作,
		/**
		 * bufImg是内存中的图片
		 * 内存是通过一些管道流,管道流里面的东西有的还没有到内存中
		 * 有时需要强制操作将管道流里面的东西压出来(到硬盘或者内存),这个操作就是flush
		 * close也可以起到一样的效果
		 */
		bufImg.flush();//清理:
		
		
		
		
		
		
		
		return bufImg; 
	}
	
	
	
	/**
	 * 
	 * @Title: qRCodeCommon
	 * @Description: TODO	二维码生成版(加logo版)
	 * @param content	二维码中的隐藏信息类容
	 * @param imgType	图片的格式		png
	 * @param size		二维码的尺寸	边长
	 * @return			返回生成的图片对象
	 * @return: BufferedImage
	 
	 * @throws IOException 
	 */
	private BufferedImage qRCodeCommon2(String content,String imgType,int size) throws IOException {
		//代码顺序调整前,注释未变化--------------------------------------------
//		BufferedImage bufImg =null;
//		/**
//		 * BufferedImage	内存中的图片
//		 * 正常情况需要对象直接new 就可以,但是bufImg = new BufferedImage()不可以,说明这个class没有无参构造
//		 * 查看源码,发现没有无参构造但是有有参构造,选择合适的有参构造
//		 * new BufferedImage(width, height, imageType)
//		 * width		int		size
//		 * height		int		size
//		 * imageType	int		BufferedImage.TYPE_INT_RGB
//		 * 
//		 * imageType 这里或者直接写1
//		 * 美术的三原色是 红、黄、蓝 ,计算机的三原色是 red green blue 简称RGB
//		 * 
//		 * 
//		 */
//		bufImg = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
//		//有了图片对象后,在通过图片对象生成一个画板
//		Graphics2D graphics2d = bufImg.createGraphics();
//		//设置画板的背景色设置为白色
//		graphics2d.setBackground(Color.WHITE);
//		/**
//		 * graphics2d.clearRect(x, y, width, height);
//		 * x、y		坐标位置,0,0就是从画板的 左上角 开始
//		 * width	二维码的边长就是画板的边长
//		 * height	二维码的边长就是画板的边长
//		 */
//		graphics2d.clearRect(0, 0, size, size);//初始化画板
//		/**
//		 * 画板的背景色设置好了,画板的大小设置好了,现在开始准备画画了(画二维码)
//		 */
//		graphics2d.setColor(Color.BLACK);//设置二维码的颜色:这里设置黑色
//		/**
//		 * 剩下的就是开始话二维码
//		 * 二维码是如何画的?
//		 * 这里简述方便理解:
//		 * 		helloworld是需要转换成二维码的隐藏信息,这里将helloworld转换成二位码的像素点
//		 * 这里具体是将helloworld隐藏信息转换成了boolean数组,转换成了boolean[][]二维数组
//		 * 二维码可以是一个平面,可以看成是一个二维数组,helloworld转换的过程中,对于在映射的过程中,
//		 * 某一个点如果满足映射标记为黑色,从而整体生成了一个二维码
//		 */
//		/**
//		 * 这里需要将传进来的字符串转化成一个二位数组boolean[][]
//		 * 
//		 * 转换成二位数组的话有需要一个Qrcode对象,这里是作为一个处理器
//		 * 
//		 * qrCodeHandler这里是作为一个处理器
//		 */
//		Qrcode qrCodeHandler = new Qrcode();
//		/**
//		 * 设置二维码的排错率。L/M/Q/H 从小到大
//		 * L	7%
//		 * M
//		 * Q
//		 * H	30%
//		 * 
//		 * 排错率越高,二维码可存储的信息越少,但是对二维码清晰度要求越小(容易扫出来)
//		 * 
//		 * 这里设置一个中间值 M
//		 */
//		qrCodeHandler.setQrcodeErrorCorrect('M');
//		/**
//		 * 二维码可以存放的信息类型 		N
//		 * N	数字(只能放数字)
//		 * A	数字+A~Z
//		 * B	所有
//		 * (一般都选B)
//		 */
//		qrCodeHandler.setQrcodeEncodeMode('B');
//		/**
//		 * 二维码的尺寸
//		 * 取值范围:1~40		数字越大二维码越大
//		 * 由于我们制定了二维码的尺寸,但是这里的尺寸只能是1~40,所以超出的话会出错
//		 * 但是如果真的使用40的话,那二维码又太小了
//		 * 所以这里为了保证这里满足需求(1~40),又能保证后面的不至于二维码太小,这里自定义一个公式:
//		 * 在满足qrCodeHandler.setQrcodeVersion(size);的情况下,
//		 * 再将size进行放大满足其他尺寸的需求,所以这部分代码我们要上移,
//		 * 先定义这里的尺寸,再将放大后的尺寸提供其他位置使用
//		 */
//		qrCodeHandler.setQrcodeVersion(size);
//	
//==========================================================================================		
		
		//代码顺序调整后,注释未变化--------------------------------------------
		/**
		 * 剩下的就是开始话二维码
		 * 二维码是如何画的?
		 * 这里简述方便理解:
		 * 		helloworld是需要转换成二维码的隐藏信息,这里将helloworld转换成二位码的像素点
		 * 这里具体是将helloworld隐藏信息转换成了boolean数组,转换成了boolean[][]二维数组
		 * 二维码可以是一个平面,可以看成是一个二维数组,helloworld转换的过程中,对于在映射的过程中,
		 * 某一个点如果满足映射标记为黑色,从而整体生成了一个二维码
		 */
		/**
		 * 这里需要将传进来的字符串转化成一个二位数组boolean[][]
		 * 
		 * 转换成二位数组的话有需要一个Qrcode对象,这里是作为一个处理器
		 * 
		 * qrCodeHandler这里是作为一个处理器
		 */
		Qrcode qrCodeHandler = new Qrcode();
		/**
		 * 设置二维码的排错率。L/M/Q/H 从小到大
		 * L	7%
		 * M
		 * Q
		 * H	30%
		 * 
		 * 排错率越高,二维码可存储的信息越少,但是对二维码清晰度要求越小(容易扫出来)
		 * 
		 * 这里设置一个中间值 M
		 */
		qrCodeHandler.setQrcodeErrorCorrect('M');
		/**
		 * 二维码可以存放的信息类型 		N
		 * N	数字(只能放数字)
		 * A	数字+A~Z
		 * B	所有
		 * (一般都选B)
		 */
		qrCodeHandler.setQrcodeEncodeMode('B');
		/**
		 * 二维码的尺寸
		 * 取值范围:1~40		数字越大二维码越大
		 * 由于我们制定了二维码的尺寸,但是这里的尺寸只能是1~40,所以超出的话会出错
		 * 但是如果真的使用40的话,那二维码又太小了
		 * 所以这里为了保证这里满足需求(1~40),又能保证后面的不至于二维码太小,这里自定义一个公式:
		 * 在满足qrCodeHandler.setQrcodeVersion(size);的情况下,
		 * 再将size进行放大满足其他尺寸的需求,所以这部分代码我们要上移,
		 * 先定义这里的尺寸,再将放大后的尺寸提供其他位置使用
		 */
		qrCodeHandler.setQrcodeVersion(size);
		
		/*
		 * qrCodeHandler.calQrcode(qrcodeData)
		 * calQrcode这个方法就可以将我们需要的信息编程boolean[][]
		 * 但是calQrcode(qrcodeData)的参数qrcodeData是一个字节数组类型
		 * 所以我们需要将传进来的string转换称byte[]
		 */
		byte[] contentBytes = content.getBytes("UTF-8");//将helloworld---->byte[]"helloworld"
		boolean[][] codeOut = qrCodeHandler.calQrcode(contentBytes);//获取到了二维码的二位数组
		
		//这里将size按照自定义规则放大到imgSize,然后更改后续的变量
		int imgSize = 67+12*(size-1);
		
		

		BufferedImage bufImg =null;
		/**
		 * BufferedImage	内存中的图片
		 * 正常情况需要对象直接new 就可以,但是bufImg = new BufferedImage()不可以,说明这个class没有无参构造
		 * 查看源码,发现没有无参构造但是有有参构造,选择合适的有参构造
		 * new BufferedImage(width, height, imageType)
		 * width		int		size
		 * height		int		size
		 * imageType	int		BufferedImage.TYPE_INT_RGB
		 * 
		 * imageType 这里或者直接写1
		 * 美术的三原色是 红、黄、蓝 ,计算机的三原色是 red green blue 简称RGB
		 * 
		 * 
		 */
		bufImg = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);
		//有了图片对象后,在通过图片对象生成一个画板
		Graphics2D graphics2d = bufImg.createGraphics();
		//设置画板的背景色设置为白色
		graphics2d.setBackground(Color.WHITE);
		/**
		 * graphics2d.clearRect(x, y, width, height);
		 * x、y		坐标位置,0,0就是从画板的 左上角 开始
		 * width	二维码的边长就是画板的边长
		 * height	二维码的边长就是画板的边长
		 */
		graphics2d.clearRect(0, 0, imgSize, imgSize);//初始化画板
		/**
		 * 画板的背景色设置好了,画板的大小设置好了,现在开始准备画画了(画二维码)
		 */
		graphics2d.setColor(Color.BLACK);//设置二维码的颜色:这里设置黑色
		/**
		 * 由于上面已经获取到了二维码的二位数组
		 * boolean[][] codeOut = qrCodeHandler.calQrcode(contentBytes);
		 * 所以现在只需要在画板中将二维数组画出来即可
		 * 
		 * 由于是二维数组,这里描绘二维码的时候需要对二维数组经行双循环遍历
		 * 由于已经生成了boolean[][],已经指明了元素的true和false,所以只需要对其中的元素进行判断
		 * true进行描黑,false就不管
		 */
		int pixoff = 2;//定义一个二维码偏移量,偏移一点避免顶格
		for (int i = 0; i < codeOut.length; i++) {
			for (int j = 0; j < codeOut.length; j++) {
				if (codeOut[j][i]) {//true进行描黑,false就不管
					/**
					 * graphics2d.fillRect(x, y, width, height);
					 * fillRect		填充长方形
					 * x\y		坐标(这里i是横坐标,j是纵坐标)
					 * 			由于x/y只是作标,代表的是一个点,所以一般使用x*3和y*3
					 * x*3和y*3	表示的是这个以x/y作标为起点的一个3*3的正方形
					 * width	3
					 * height	3
					 * 
					 * 由于二维码的一般是居中,所以这里需要整体给一个偏移量
					 * 所以需要提前在循环外面定义一个像素偏移量
					 * 
					 * 所以这里需要将定义好的偏移量加载坐标轴里面
					 */
					graphics2d.fillRect(i*3+pixoff, j*3+pixoff, 3, 3);
				}
			}
		}
		//增加logo
		/**
		 * 增加logo:
		 * 1.加载硬盘里面的logo图片
		 * 2.将logo图片添加覆盖到二维码的中心
		 * 
		 * 注意:logo选取不可过大,过大可能导致显示不出来或者二维码扫不出来
		 */
		//将硬盘里面的logo图片,加载为一个Image对象
		String logoPath = "src/logo.jpg";
		Image readLogo = ImageIO.read(new File(logoPath));
		/*
		 * 在以生成的二维码图像上画Logo
		 * graphics2d	画笔
		 * drawImage(img, x, y, width, height, observer)
		 * img			img对象 	logo
		 * x/y			logo图像的坐标位置	imgSize*2/5
		 * width/height	logo的宽高
		 * observer		null	这里不用处理,取null
		 * 
		 * 将二维码横竖各切4刀均分,logo应该添加在最中间的那一块,现在就是定位logo起始坐标
		 * 由于logo位于最中央,所以logo的左上角应该位于二维码的2/5处
		 * 
		 * 上面已经定义了二维码的尺寸大小	imgSize
		 * int imgSize = 67+12*(size-1);
		 * 这里可以直接使用即可
		 * 
		 * 那么此时logo的尺寸应该为多大呢?
		 * 由于这个是将二维码横竖五等分,且logo位于二维码最中间那一块
		 * 那么logo的边长尺寸即为二维码边长尺寸的1/5
		 * 
		 * 由于二维码已经生成,这里可以获取整个二维码宽高的尺寸并取1/5作为logo的宽高
		 * 
		 * 
		 */
		//取整个二维码宽高的尺寸并取1/5作为logo的宽高
		int maxHeight = bufImg.getHeight();
		int maxWidth = bufImg.getWidth();
		graphics2d.drawImage(readLogo, imgSize*2/5, imgSize*2/5, maxWidth/5,maxHeight/5, null);
//		graphics2d.drawImage(readLogo, imgSize*3/7, imgSize*3/7, maxWidth/7,maxHeight/7, null);
		
		//操作完毕后需要释放画板空间
		graphics2d.dispose();
		//画完以后的话,流操作一般需要close或者flush一下输出出来
		//清理:管道流操作,
		/**
		 * bufImg是内存中的图片
		 * 内存是通过一些管道流,管道流里面的东西有的还没有到内存中
		 * 有时需要强制操作将管道流里面的东西压出来(到硬盘或者内存),这个操作就是flush
		 * close也可以起到一样的效果
		 */
		bufImg.flush();//清理:
		
		
		return bufImg; 
	}
	
	
	
	
	 //解密:二维码------------>文字信息
	/**
	 * 刚才是使用手机可以读出来二维码的信息,现在需要使用代码读取图片的信息
	 */
	/**
	 * 
	 * @Title: decoderQRCode
	 * @Description: TODO	二维码解密
	 * @param imgPath	解密二维码文件路径
	 * @return
	 * @return: String
	 
	 * @throws IOException 
	 */
	public String decoderQRCode(String imgPath) throws IOException{
		//1.受限获取一个图片对象(解密二维码图片对象)
		//BufferedImage	内存中的图片,将硬盘中的imgPath图片加载到内存中BufferedImage
		BufferedImage bufImg = ImageIO.read(new File(imgPath));
		//解密
		/**
		 * decoder	解密对象
		 */
		QRCodeDecoder decoder = new QRCodeDecoder();
		/**
		 * decode(qrCodeImage)
		 * 解密函数的参数为qrCodeImage
		 * 也就是解密的对象必须是qrCodeImage对象
		 * 所以这里需要先准备qrCodeImage对象
		 * 
		 * 但是QRCodeImage是一个接口,并且没有对应的实现类
		 * 所以这里需要QRCodeImage对象只能创建一个类来实现QRCodeImage接口来创建对象
		 * 这里需要提前创建一个类对象实现QRCodeImage
		 * decoder.decode(TwoDimensionalCodeImage)即可
		 * 
		 * 但是这里需要解密的是bufImg二维码对象,直接把TwoDimensionalCodeImage对象放进去没有意义
		 * 
		 * 那么这里可以在TwoDimensionalCodeImage类里面创建一个BufferedImage对象
		 * 但是创建的BufferedImage对象没有值,
		 * 这里可以使用构造方法给TwoDimensionalCodeImage里面的BufferedImage赋值
		 * 
		 * 完善好TwoDimensionalCodeImage里面的函数后即可补全decoder.decode(qrCodeImage)
		 */
		//将内存中的bufImg转换成实现了QRCodeImage接口的TwoDimensionalCodeImage对象
		TwoDimensionalCodeImage tdcImage = new TwoDimensionalCodeImage(bufImg);
		//解密QRCodeImage类型对象,解密的结果是一个字节数组
		byte[] bytes = decoder.decode(tdcImage);
		//将字节数组转换成字符串,由于避免出现乱码,这里设定编码格式utf-8
		String content = new String(bytes, "UTF-8");
		
		return content;//将解码完成的字符串返回
	}

}

辅助类

/**  
 * Copyright © 2020wangylCompany. All rights reserved.
 *
 * @Title: TwoDimensionalCodeImage.java
 * @Prject: MyTestDemo
 * @Package: qrcode
 * @Description: TODO
 * @version: V1.0  
 */

package qrcode;

import java.awt.image.BufferedImage;

import jp.sourceforge.qrcode.data.QRCodeImage;

/**
 * @ClassName: TwoDimensionalCodeImage
 * @Description: TODO
 * 
 *
 */

public class  TwoDimensionalCodeImage implements QRCodeImage{
	
	
	/**
	 * 由于decoder.decode(qrCodeImage)需要的是QRCodeImage
	 * 
	 * 但是需要解析的是BufferedImage对象,所以我们需要在类里面创建一个BufferedImage
	 * 
	 * 然后通构造器给类里面的BufferedImage对象赋值
	 */
	BufferedImage bufImg;//内存中的二维码对象
	
	public TwoDimensionalCodeImage(BufferedImage bufImg) {
		this.bufImg=bufImg;
	}
	
	
	
	
	

	/* (non Javadoc)
	 * @Title: getWidth
	 * @Description: TODO
	 * @return
	 * @see jp.sourceforge.qrcode.data.QRCodeImage#getWidth()
	 */
	@Override
	public int getWidth() {
		return bufImg.getWidth();
	}

	/* (non Javadoc)
	 * @Title: getHeight
	 * @Description: TODO
	 * @return
	 * @see jp.sourceforge.qrcode.data.QRCodeImage#getHeight()
	 */
	@Override
	public int getHeight() {
		return bufImg.getHeight();
	}

	/* (non Javadoc)
	 * @Title: getPixel		像素点
			由于是解密,解密需要知道所有的像素点
			像素点就是获取某一个坐标点的颜色值,由于加密是通过true/false上色的
	
	 * @Description: TODO
	 * @param paramInt1
	 * @param paramInt2
	 * @return
	 * @see jp.sourceforge.qrcode.data.QRCodeImage#getPixel(int, int)
	 */
	@Override
	public int getPixel(int paramInt1, int paramInt2) {
		return bufImg.getRGB(paramInt1, paramInt2);
	}

}

测试类

/**  
 * Copyright © 2020wangylCompany. All rights reserved.
 *
 * @Title: Test.java
 * @Prject: MyTestDemo
 * @Package: qrcode
 * @Description: TODO
 * @version: V1.0  
 */

package qrcode;

import java.io.IOException;

/**
 * @ClassName: Test
 * @Description: TODO 生成二维码
 * 
 *
 */

public class Test {
	
	public static void main(String[] args){
		//生成二维码
		/**
		 * 生成二维码  src/二维码.png
		 * 文字信息、网址信息:
		 */
		String imgPath ="src/二维码.png";//生成二维码的路径文件名
		String imgPath2 ="src/l2.png";//添加logo路径的文件名
		//存放字符串
//		String content = "helloworld";
		//存放网址,扫描二维码会实现网页的跳转操作
		String content2 = "http//:www.baidu.com";
		
		
		
		//生成二维码
		/**
		 * 加密:文字信息---------->二维码
		 */
		//新建一个二维码生成的工具类对象
		QRCodeUtil qrCodeUtil = new QRCodeUtil();
		//调用创建的加密的加密方法,根据参数提示将参数补全
		/**
		 * qrCodeUtil.encoderQRCode(content, imgPath, imgType, size);
		 * 
		 * size 图片大小,只能输入1~40的整数值
		 * 这里的size尺寸大小会影响到数据的存储解码,当解码出现问题的时候可能是这个二维码太小
		 * 需要将其调大一些可以存储更多的信息
		 */
		try {
			qrCodeUtil.encoderQRCode(content2, imgPath, "png", 17);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		/**
		 * 加密:文字信息---------->二维码
		 * 解密:二维码------------>文字信息
		 */
		try {
			String imgContent = qrCodeUtil.decoderQRCode(imgPath);
			System.out.println(imgContent);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
}

QRCode存在部分解析不出来的问题。(以上没有对异常进行处理)

  • 1
    点赞
  • 0
    评论
  • 3
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值