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

原创
2014/04/01 13:31
阅读数 5.7W

二维码生成主要使用了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;
	}
}



展开阅读全文
打赏
6
29 收藏
分享
加载中
12楼 +1,可以不生成文件,然后操作对象,再以流的形式输出吗
2017/08/14 14:48
回复
举报
二维码的图片保存在BufferedImage 对象中不能直接进行操作吗?必须要生成文件到磁盘?
2017/07/18 14:09
回复
举报
#jfinal30[358]#
2016/04/22 17:21
回复
举报
Ryan-瑞恩博主

引用来自“hezc”的评论

能否把相关的JAR包也共享一下
http://maven.oschina.net/index.html#nexus-search;quick~zxing
2015/05/15 10:47
回复
举报
能否把相关的JAR包也共享一下
2015/05/15 10:38
回复
举报

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

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

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

你试试。。。。

引用来自“minjasmine”的评论

试过了,logo大的话机识别不了了
纠错级别设置的高一些没问题。 有可能是你的图片真的挡住太多了
2014/09/30 23:23
回复
举报

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

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

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

你试试。。。。
试过了,logo大的话机识别不了了
2014/06/21 08:45
回复
举报
Ryan-瑞恩博主

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

您好,logo会不会挡住二维码的位置影响识别啊
你试试。。。。
2014/06/20 17:39
回复
举报
您好,logo会不会挡住二维码的位置影响识别啊
2014/06/20 16:50
回复
举报
不错。你写了按比例缩小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;

2014/06/20 08:20
回复
举报
更多评论
打赏
13 评论
29 收藏
6
分享
返回顶部
顶部