天天看点

Google 开源工具 ZXing进行二维码编码 / add logo / 解码

先下载相关的 jar 包 :

Google 开源工具 ZXing进行二维码编码 / add logo / 解码

然后开始撸代码,其实代码逻辑挺简单的,大概流程就是:

1 现在内存生成一张图片

2 将你想转化为二维码的信息打成二维数组分布在图片上

3 设置相关的参数,如排错率, 尺寸,编码方式等

4 最后利用生成的二维码在给其加入 logo 利用相应的画笔

5 利用图片流写入指定的文件路径

//加密方法名,及相应传入的参数 
public void ZXingEncode(String content , String imgPath, String logo , String format , int width , int height)
//在内存中生成图片
BufferedImage im = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//将需要加密的文字 ---》矩阵数组  
// BarcodeFormat.QR_CODE : 解析类型二维码(还可以设置条形码啥的), 最后一个参数就是设置基本参数的对象
BitMatrix bm = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints); 
//用来设置基本参数,出错率,编码方式等
Map<EncodeHintType , Object> hints = new HashMap<>();  
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);   //设置排错率
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");  // 编码方式
hints.put(EncodeHintType.MARGIN, 1);   // 就是二维码跟图片周围边框的距离

	//遍历刚刚的二维数组,如果存在信息则设置为黑色
		for(int x=0 ; x<width ; x++)
			for(int y=0 ; y<height ; y++)  {
				   im.setRGB(x, y, bm.get(x, y) ? BLACK : WHITE);  
			}

		//产生logo 二维码图片
	   im =	DrawLogoUtils.CreateLogo(im, logo);
		
		// 二维码存放位置
		File f = new File(imgPath);		
		// 生成图片
		ImageIO.write(im, format, f);
           

添加 logo 的方法及大概流程:

1 将磁盘内的图片读取到内存

2 指定 logo 在二维码上的位置,并将其黑白部分覆盖

3 加入logo与二维之间的特效如 灰色边框,logo的四个角为圆形啥的

4 完成操作(对于相关的操作可以理解成画板(上面有二维码图片)和一只画笔)

public static  BufferedImage CreateLogo( BufferedImage img , String logo) 
	 
//画 logo --> 磁盘图片 load to 内存
 BufferedImage log = ImageIO.read(new File(logo));
     int h =  img.getHeight(); //获取二维码的长度
	 int w = img.getWidth(); // 获取二维码的宽度
 	 // 在画板上画 纯 logo 图片 , 画板自带二维码
  Graphics2D g2 = img.createGraphics();
     //将logo放置指定二维码位置
   g2.drawImage(log,  w*1/5, h*1/5  ,  w*1/5, h*1/5, null);
      // 利用圆笔头画白色方框( 笔头粗细 , 笔头形状 , 两者交界处形状)
	     BasicStroke pen = new BasicStroke(5 , BasicStroke.CAP_ROUND , BasicStroke.JOIN_ROUND);
	     //将画笔与画板关联
	     g2.setStroke(pen);
	     
	     // 设置特效部分
	     
	     //用笔在logo 旁边画一个圆角正方形
	     RoundRectangle2D.Float round = new RoundRectangle2D.Float( w*1/5, h*1/5  ,  w*1/5, h*1/5,  BasicStroke.CAP_ROUND , BasicStroke.JOIN_ROUND);
	     //为边框设置颜色
	     g2.setColor(Color.WHITE);
	     //开始画
	     g2.draw(round);
	     //完成绘画,关闭操作
	     g2.dispose();
	     log.flush();
	     
		return img;

           

在来说说其解码的大体流程:

1 将二维码加载进内存

2 将相应的二维数组信息转化为文字信息

// 解码
	public void decodeImg(File f) throws Exception
	{
		// 如果二维码不存在则停止操作
		if ( !f.exists() ) return ;
		// 将二维码加载进内存
		BufferedImage image= ImageIO.read(f);
		//解码工具类
		MultiFormatReader reader = new MultiFormatReader();
		// 代码逻辑解析在下面
		LuminanceSource source = new BufferedImageLuminanceSource(image);
		Binarizer binarizer = new HybridBinarizer(source);
		BinaryBitmap bitmap = new BinaryBitmap(binarizer);
		//设置解码时的编码方式
		Map map = new HashMap<>();
		map.put(EncodeHintType.CHARACTER_SET, "utf-8");
		//传入相关参数
		Result res = reader.decode(bitmap , map);
		//打印解码信息
		System.out.println(res.toString());
           

代码逻辑解析:

Google 开源工具 ZXing进行二维码编码 / add logo / 解码

此时解码需要一个 BinaryBitmap 那我们就创建一个 BinaryBitmap:

Google 开源工具 ZXing进行二维码编码 / add logo / 解码

那么通过提示又发现需要一个 Binarizer 类型的参数,那我们在创建 这个类:

Google 开源工具 ZXing进行二维码编码 / add logo / 解码

Binarizer 是 abstract 类,则创建其子类,通过提示发现需要 LuminanceSource类,那我们在创建这个类:

Google 开源工具 ZXing进行二维码编码 / add logo / 解码

同样的逻辑,这是一个抽象类,需要由其子类实现,那通过提示看见 BufferedImage 这个提示就把我们加载进内存的图片参数传进去即可,不得不说有点麻烦,但逻辑性又不是那么的强。

总结: 其实和这篇内容

Java 生成二维码代码解析

差不多,但使用的工具不同而已,大体的思路无非就是将需要加密的信息打散成二维数组分布在设定好长宽的图片上,通过遍历,有内容的点则设置为黑色。添加 logo 的思路也差不多,只需要指定 logo 在二维码上的位置,然后覆盖即可。