文档章节

ZXing生成二维码,以及给二维码添加Logo

Ryan-瑞恩
 Ryan-瑞恩
发布于 2014/04/01 13:31
字数 1774
阅读 5.1W
收藏 29

二维码生成主要使用了Google的zxing开源包。具体jar去官网下载!

类引入:

package com.rayn.qt1;


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;


生成代码如下所示,

1.二维码属性设置

    /**
* 设置二维码的格式参数

* @return
*/
public Map<EncodeHintType, Object> getDecodeHintType()
{
// 用于设置QR二维码参数
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
// 设置QR二维码的纠错级别(H为最高级别)具体级别信息
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
// 设置编码方式
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.MAX_SIZE, 350);
hints.put(EncodeHintType.MIN_SIZE, 100);


return hints;
}

2.二维码的数据信息初始化

/**
* 构建初始化二维码

* @param bm
* @return
*/
public BufferedImage fileToBufferedImage(BitMatrix bm)
{
BufferedImage image = null;
try
{
int w = bm.getWidth(), h = bm.getHeight();
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);


for (int x = 0; x < w; x++)
{
for (int y = 0; y < h; y++)
{
image.setRGB(x, y, bm.get(x, y) ? 0xFF000000 : 0xFFCCDDEE);
}
}


}
catch (Exception e)
{
e.printStackTrace();
}
return image;
}

3.二维码生成

    /**
* 生成二维码bufferedImage图片

* @param content
*            编码内容
* @param barcodeFormat
*            编码类型
* @param width
*            图片宽度
* @param height
*            图片高度
* @param hints
*            设置参数
* @return
*/
public BufferedImage getQR_CODEBufferedImage(String content, BarcodeFormat barcodeFormat, int width, int height, Map<EncodeHintType, ?> hints)
{
MultiFormatWriter multiFormatWriter = null;
BitMatrix bm = null;
BufferedImage image = null;
try
{
multiFormatWriter = new MultiFormatWriter();


// 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数
bm = multiFormatWriter.encode(content, barcodeFormat, width, height, hints);


int w = bm.getWidth();
int h = bm.getHeight();
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);


// 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
for (int x = 0; x < w; x++)
{
for (int y = 0; y < h; y++)
{
image.setRGB(x, y, bm.get(x, y) ? 0xFF000000 : 0xFFCCDDEE);
}
}
}
catch (WriterException e)
{
e.printStackTrace();
}
return image;
}

4.二维码的生成输出文件或输出流进行使用

/**
* 将二维码生成为文件

* @param bm
* @param imageFormat
* @param file
*/
public void decodeQR_CODE2ImageFile(BitMatrix bm, String imageFormat, File file)
{
try
{
if (null == file || file.getName().trim().isEmpty())
{
throw new IllegalArgumentException("文件异常,或扩展名有问题!");
}


BufferedImage bi = fileToBufferedImage(bm);
ImageIO.write(bi, "jpeg", file);
}
catch (Exception e)
{
e.printStackTrace();
}
}


/**
* 将二维码生成为输出流

* @param content
* @param imageFormat
* @param os
*/
public void decodeQR_CODE2OutputStream(BitMatrix bm, String imageFormat, OutputStream os)
{
try
{
BufferedImage image = fileToBufferedImage(bm);
ImageIO.write(image, imageFormat, os);
}
catch (Exception e)
{
e.printStackTrace();
}
}

5.给二维码中间的部分添加Logo图片。类似微信那样的

/**
* 给二维码图片添加Logo

* @param qrPic
* @param logoPic
*/
public void addLogo_QRCode(File qrPic, File logoPic, LogoConfig logoConfig)
{
try
{
if (!qrPic.isFile() || !logoPic.isFile())
{
System.out.print("file not find !");
System.exit(0);
}


/**
* 读取二维码图片,并构建绘图对象
*/
BufferedImage image = ImageIO.read(qrPic);
Graphics2D g = image.createGraphics();


/**
* 读取Logo图片
*/
BufferedImage logo = ImageIO.read(logoPic);

int widthLogo = logo.getWidth(), heightLogo = logo.getHeight();

// 计算图片放置位置
int x = (image.getWidth() - widthLogo) / 2;
int y = (image.getHeight() - logo.getHeight()) / 2;


//开始绘制图片
g.drawImage(logo, x, y, widthLogo, heightLogo, null);
g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
g.setStroke(new BasicStroke(logoConfig.getBorder()));
g.setColor(logoConfig.getBorderColor());
g.drawRect(x, y, widthLogo, heightLogo);

g.dispose();

ImageIO.write(image, "jpeg", new File("D:/newPic.jpg"));
}
catch (Exception e)
{
e.printStackTrace();
}
}

Logo辅助类:

public class LogoConfig
{
// logo默认边框颜色
public static final Color DEFAULT_BORDERCOLOR = Color.WHITE;
// logo默认边框宽度
public static final int DEFAULT_BORDER = 2;
// logo大小默认为照片的1/5
public static final int DEFAULT_LOGOPART = 5;


private final int border = DEFAULT_BORDER;
private final Color borderColor;
private final int logoPart;


/**
* Creates a default config with on color {@link #BLACK} and off color
* {@link #WHITE}, generating normal black-on-white barcodes.
*/
public LogoConfig()
{
this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART);
}


public LogoConfig(Color borderColor, int logoPart)
{
this.borderColor = borderColor;
this.logoPart = logoPart;
}


public Color getBorderColor()
{
return borderColor;
}


public int getBorder()
{
return border;
}


public int getLogoPart()
{
return logoPart;
}
}

6.二维码解析

/**
* 二维码的解析

* @param file
*/
public void parseQR_CODEImage(File file)
{
try
{
MultiFormatReader formatReader = new MultiFormatReader();


// File file = new File(filePath);
if (!file.exists())
{
return;
}


BufferedImage image = ImageIO.read(file);


LuminanceSource source = new BufferedImageLuminanceSource(image);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);


Map hints = new HashMap();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");


Result result = formatReader.decode(binaryBitmap, hints);


System.out.println("result = " + result.toString());
System.out.println("resultFormat = " + result.getBarcodeFormat());
System.out.println("resultText = " + result.getText());
}
catch (Exception e)
{
e.printStackTrace();
}
}

package com.rayn.qt1;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

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

public class ZXingPic
{
	public static void main(String[] args) throws WriterException
	{
		String content = "【优秀员工】恭喜您,中奖了!!!领取方式,请拨打电话:15998099997*咨询。";
		String filePath = "D:/weibow.jpg";

		// if(args.length != 2)
		// {
		// System.out.println("没有内容,图片生成失败!");
		// System.exit(0);
		// }

		try
		{
			File file = new File(filePath);
			if (file.exists())
			{
				file = new File("D:/", new Date().getTime() + ".jpg");
			}

			ZXingPic zp = new ZXingPic();

			BufferedImage bim = zp.getQR_CODEBufferedImage(content, BarcodeFormat.QR_CODE, 300, 300, zp.getDecodeHintType());

			ImageIO.write(bim, "jpeg", file);

			zp.addLogo_QRCode(file, new File("D:/123123123.jpg"), new LogoConfig());
			
			Thread.sleep(5000);
			zp.parseQR_CODEImage(new File("D:/newPic.jpg"));
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * 给二维码图片添加Logo
	 * 
	 * @param qrPic
	 * @param logoPic
	 */
	public void addLogo_QRCode(File qrPic, File logoPic, LogoConfig logoConfig)
	{
		try
		{
			if (!qrPic.isFile() || !logoPic.isFile())
			{
				System.out.print("file not find !");
				System.exit(0);
			}

			/**
			 * 读取二维码图片,并构建绘图对象
			 */
			BufferedImage image = ImageIO.read(qrPic);
			Graphics2D g = image.createGraphics();

			/**
			 * 读取Logo图片
			 */
			BufferedImage logo = ImageIO.read(logoPic);
			
			int widthLogo = logo.getWidth(), heightLogo = logo.getHeight();
			
			// 计算图片放置位置
			int x = (image.getWidth() - widthLogo) / 2;
			int y = (image.getHeight() - logo.getHeight()) / 2;

			//开始绘制图片
			g.drawImage(logo, x, y, widthLogo, heightLogo, null);
			g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
			g.setStroke(new BasicStroke(logoConfig.getBorder()));
			g.setColor(logoConfig.getBorderColor());
			g.drawRect(x, y, widthLogo, heightLogo);
			
			g.dispose();
			
			ImageIO.write(image, "jpeg", new File("D:/newPic.jpg"));
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * 二维码的解析
	 * 
	 * @param file
	 */
	public void parseQR_CODEImage(File file)
	{
		try
		{
			MultiFormatReader formatReader = new MultiFormatReader();

			// File file = new File(filePath);
			if (!file.exists())
			{
				return;
			}

			BufferedImage image = ImageIO.read(file);

			LuminanceSource source = new BufferedImageLuminanceSource(image);
			Binarizer binarizer = new HybridBinarizer(source);
			BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);

			Map hints = new HashMap();
			hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");

			Result result = formatReader.decode(binaryBitmap, hints);

			System.out.println("result = " + result.toString());
			System.out.println("resultFormat = " + result.getBarcodeFormat());
			System.out.println("resultText = " + result.getText());
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * 将二维码生成为文件
	 * 
	 * @param bm
	 * @param imageFormat
	 * @param file
	 */
	public void decodeQR_CODE2ImageFile(BitMatrix bm, String imageFormat, File file)
	{
		try
		{
			if (null == file || file.getName().trim().isEmpty())
			{
				throw new IllegalArgumentException("文件异常,或扩展名有问题!");
			}

			BufferedImage bi = fileToBufferedImage(bm);
			ImageIO.write(bi, "jpeg", file);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * 将二维码生成为输出流
	 * 
	 * @param content
	 * @param imageFormat
	 * @param os
	 */
	public void decodeQR_CODE2OutputStream(BitMatrix bm, String imageFormat, OutputStream os)
	{
		try
		{
			BufferedImage image = fileToBufferedImage(bm);
			ImageIO.write(image, imageFormat, os);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * 构建初始化二维码
	 * 
	 * @param bm
	 * @return
	 */
	public BufferedImage fileToBufferedImage(BitMatrix bm)
	{
		BufferedImage image = null;
		try
		{
			int w = bm.getWidth(), h = bm.getHeight();
			image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

			for (int x = 0; x < w; x++)
			{
				for (int y = 0; y < h; y++)
				{
					image.setRGB(x, y, bm.get(x, y) ? 0xFF000000 : 0xFFCCDDEE);
				}
			}

		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return image;
	}

	/**
	 * 生成二维码bufferedImage图片
	 * 
	 * @param content
	 *            编码内容
	 * @param barcodeFormat
	 *            编码类型
	 * @param width
	 *            图片宽度
	 * @param height
	 *            图片高度
	 * @param hints
	 *            设置参数
	 * @return
	 */
	public BufferedImage getQR_CODEBufferedImage(String content, BarcodeFormat barcodeFormat, int width, int height, Map<EncodeHintType, ?> hints)
	{
		MultiFormatWriter multiFormatWriter = null;
		BitMatrix bm = null;
		BufferedImage image = null;
		try
		{
			multiFormatWriter = new MultiFormatWriter();

			// 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数
			bm = multiFormatWriter.encode(content, barcodeFormat, width, height, hints);

			int w = bm.getWidth();
			int h = bm.getHeight();
			image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

			// 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
			for (int x = 0; x < w; x++)
			{
				for (int y = 0; y < h; y++)
				{
					image.setRGB(x, y, bm.get(x, y) ? 0xFF000000 : 0xFFCCDDEE);
				}
			}
		}
		catch (WriterException e)
		{
			e.printStackTrace();
		}
		return image;
	}

	/**
	 * 设置二维码的格式参数
	 * 
	 * @return
	 */
	public Map<EncodeHintType, Object> getDecodeHintType()
	{
		// 用于设置QR二维码参数
		Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
		// 设置QR二维码的纠错级别(H为最高级别)具体级别信息
		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
		// 设置编码方式
		hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
		hints.put(EncodeHintType.MAX_SIZE, 350);
		hints.put(EncodeHintType.MIN_SIZE, 100);

		return hints;
	}
}

class LogoConfig
{
	// logo默认边框颜色
	public static final Color DEFAULT_BORDERCOLOR = Color.WHITE;
	// logo默认边框宽度
	public static final int DEFAULT_BORDER = 2;
	// logo大小默认为照片的1/5
	public static final int DEFAULT_LOGOPART = 5;

	private final int border = DEFAULT_BORDER;
	private final Color borderColor;
	private final int logoPart;

	/**
	 * Creates a default config with on color {@link #BLACK} and off color
	 * {@link #WHITE}, generating normal black-on-white barcodes.
	 */
	public LogoConfig()
	{
		this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART);
	}

	public LogoConfig(Color borderColor, int logoPart)
	{
		this.borderColor = borderColor;
		this.logoPart = logoPart;
	}

	public Color getBorderColor()
	{
		return borderColor;
	}

	public int getBorder()
	{
		return border;
	}

	public int getLogoPart()
	{
		return logoPart;
	}
}



© 著作权归作者所有

Ryan-瑞恩

Ryan-瑞恩

粉丝 152
博文 245
码字总数 189488
作品 0
西安
后端工程师
私信 提问
加载中

评论(13)

youyua
youyua
12楼 +1,可以不生成文件,然后操作对象,再以流的形式输出吗
easymbol
easymbol
二维码的图片保存在BufferedImage 对象中不能直接进行操作吗?必须要生成文件到磁盘?
侠客行
侠客行
#jfinal30[358]#
Ryan-瑞恩
Ryan-瑞恩 博主

引用来自“hezc”的评论

能否把相关的JAR包也共享一下
http://maven.oschina.net/index.html#nexus-search;quick~zxing
hezc
hezc
能否把相关的JAR包也共享一下
小杨阿哥哥
小杨阿哥哥

引用来自“周培园”的评论

您好,logo会不会挡住二维码的位置影响识别啊

引用来自“Rayn-瑞恩”的评论

你试试。。。。

引用来自“minjasmine”的评论

试过了,logo大的话机识别不了了
纠错级别设置的高一些没问题。 有可能是你的图片真的挡住太多了
minjasmine
minjasmine

引用来自“周培园”的评论

您好,logo会不会挡住二维码的位置影响识别啊

引用来自“Rayn-瑞恩”的评论

你试试。。。。
试过了,logo大的话机识别不了了
Ryan-瑞恩
Ryan-瑞恩 博主

引用来自“周培园”的评论

您好,logo会不会挡住二维码的位置影响识别啊
你试试。。。。
minjasmine
minjasmine
您好,logo会不会挡住二维码的位置影响识别啊
小杨阿哥哥
小杨阿哥哥
不错。你写了按比例缩小LOGO。但是代码里没有用按比例后的LOGO宽度和高度啊。。
改后应该是这样的:

int widthLogo = image.getWidth()/logoConfig.getLogoPart(), heightLogo = image.getHeight()/logoConfig.getLogoPart();

// 计算图片放置位置
int x = (image.getWidth() - widthLogo) / 2;
int y = (image.getHeight() - heightLogo) / 2;

生成二维码的开源工具对比(附源码了呀!)

原文:生成二维码的开源工具对比(附源码了呀!) 某天发现生成二维码的工具(zxing)运行的很慢,于是乎上网上寻找生成二维码的工具,发现常见的开源工具有如下三种: Zxing(zxing.dll) Th...

杰克.陈
2018/07/03
0
0
zxing 如何识别反转二维码

说起二维码扫描,估计很多人用的是 zxing 吧。 然而 zxing 虽然好用,但是却有一些坑。 这边分析一下自己实际项目遇到的一个坑。 什么坑呢? 下面举个栗子你就懂了。 这边生成二维码使用的是...

AndroidTraveler
2018/07/23
0
0
利用iText和zxing生成和读pdf417二维码

前面的一些博文中已经提到了zxing这个开源工具生成和读取二维码图片,仅从学习的角度来看,可以告一个段落。在实际的生产环境中,应用zxing生成和读取二维码,却存在一些问题: 使用扫描枪读...

彭苏云
2014/03/06
3.6K
0
ZXing读写二维码,桌面和手机的不同用法

虽然ZXing是用Java实现的Barcode开源库,但是并不代表桌面上实现的Barcode应用在手机上也可以直接使用。因为Android的Java接口有很多是不同的。这里分享下Java Barcode生成和读取的不同用法。...

yushulx
2015/08/18
828
0
Java js 生成二维码 解析二维码

1.二维码分类   二维条码也有许多不同的码制,就码制的编码原理而言,通常分为三种类型。 线性堆叠式二维码 编码原理: 建立在一维条码基础之上,按需要堆积成两行或多行。 图示: 2. 矩阵...

haoyuehong
2018/06/28
193
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring基础

主要用于service层; 轻量级java开发框架; 各层 web层:struts,spring-MVC service层:spring dao层:hibernate,mybatis , jdbcTemplate --> spring-data Spring核心:控制反转IOC 切面编...

七宝1
13分钟前
19
0
解决overflow+border-radius+transform圆角问题

网上还有其他版本,但是对我来说都不好使,下面是我在Chrome上的代码。overflow:hidden依然是不能正常使用,换成unset就可以,读者如果有更好的解决方案,请留言,谢谢。 <figure> <img...

hi懒喵
18分钟前
39
0
《C语言》—— 数组

书籍使我变成了一个幸福的人,使我的生活变成轻松而舒适的诗。——高尔基 本文已经收录至我的GitHub,欢迎大家踊跃star 和 issues。 https://github.com/midou-tech/articles 点关注,不迷路!...

龙跃十二
31分钟前
60
0
Java小案例: 1000以内的水仙花数

要求在控制台分别展示1000以内的水仙花数。 如下:↓ 水仙花数规则: 水仙花数至少是一个3位数 每位数字的立方数的累加和,正好等于该数字本身。 例如:153就是一个水仙花数。每位数字分别...

漫路h
昨天
66
0
centos 防火墙端口设置

查看开放的端口号 firewall-cmd --lists-all 设置开放的端口号 firewall-cmd --add-service=http --permanent 1. //--permanent表示永久生效,不加这个参数的话只会针对本次执行完命令生效,重...

ACE_LCX
昨天
25
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部