二维码的功能、特点及使用Java生成带logo的二维码

二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化点。

1. 二维码主要特点

二维条码是一种高密度、高信息含量的便携式数据文件,是实现证件及卡片等大容量、高可靠性信息自动存储、携带并可用机器自动识读的理想手段。二维条码具有如下特点:

1、信息容量大根据不同的条空比例每平方英寸可以容纳250到1100个字符。在国际标准的证卡有效面积上(相当于信用卡面积的2/3,约500个汉字信息。这种二维条码比普通条码信息容量高几十倍,也高于磁卡。

2、编码范围广二维条码可以将照片、指纹、掌纹、签字、声音、文字等凡可数字化的信息进行编码。

3、保密、防伪性能好二维条码具有信息不可改写等多重防伪特性,它可以采用密码防伪、软件加密及利用所包含的信息如指纹、照片等进行防伪,因此具有较强的保密防伪性能。

4、译码可靠性高普通条码的译码错误率约为百分之二左右,而二维条码的误码率不超过千万分之一,译码可靠性极高。

5、修正错误能力强二维条码采用了世界上最先进的数字纠错理论,如果破损面积不超过50%,条码由于沾污、破损等所丢失的信息,可以照常被破译出。

6、容易制作且成本很低利用现有的点阵、激光、喷墨、热敏/热转印、制卡机等打印技术,即可在纸张、卡片、PVC、甚至金属表面上印出二维条码。由此所增加的费用仅是油墨的成本。

7、条码符号的形状可变同样的信息量,二维条码形状可以根据载体面积及美工设计等进行自我调整。

2. QRcode

QR(Quick-Response) code是被广泛使用的一种二维码,解码速度快。它可以存储多用类型。如下图时一个qrcode的基本结构,其中:

I.测图形、位置探测图形分隔符、定位图形:用于对二维码的定位,对每个QR码来说,位置都是固定存在的,只是大小规格会有所差异;

II.校正图形:规格确定,校正图形的数量和位置也就确定了;

III.格式信息:表示改二维码的纠错级别,分为L、M、Q、H;

IV.版本信息:即二维码的规格,QR码符号共有40种规格的矩阵(一般为黑白色),从21x21(版本1),到177x177(版本40),每一版本符号比前一版本 每边增加4个模块。

V. 数据和纠错码字:实际保存的二维码信息,和纠错码字(用于修正二维码损坏带来的错误)。

更多二维码的生成细节可戳这里

3. 带中心logo图片的二维码生成

使用先导入google开源的zxing和j2se的jar包

(1) 二维码的数据模型

package com.Lin;

public class Qrcode {
	private String content;    	//二维码内容
	private String filePath;   	//文件存放路径
	private String fileName;   	//文件名称
	private int width;         	//图像宽度
	private int height;  	   	//图像高度
	private String format;     	//图像类型,eg:png
	private int onColor = 0xFF000000;  //默认为黑
	private int offColor = 0xFFFFFFFF; //背景颜色,默认为白

	//无参的构造函数
	public Qrcode(){}

	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getFilePath() {
		return filePath;
	}
	public void setFilePath(String filePath) {
		this.filePath = filePath;
	}
	public String getFileName() {
		return fileName;
	}
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	public int getWidth() {
		return width;
	}
	public void setWidth(int width) {
		this.width = width;
	}
	public int getHeight() {
		return height;
	}
	public void setHeight(int height) {
		this.height = height;
	}
	public String getFormat() {
		return format;
	}
	public void setFormat(String format) {
		this.format = format;
	}

	public int getOnColor() {
		return onColor;
	}

	public void setOnColor(int onColor) {
		this.onColor = onColor;
	}

	public int getOffColor() {
		return offColor;
	}

	public void setOffColor(int offColor) {
		this.offColor = offColor;
	}

}

(2) 生成二维码图像

	/**
	 * 生成二维码图像
	 * @param q          二维码模型
	 * @param logoPath   中心logo的存储路径,为null时没中心logo
	 * @throws WriterException
	 * @throws IOException
	 */
	public void encode(Qrcode q, String logoPath) throws WriterException, IOException {
        BitMatrix bitMatrix;    

        Hashtable<EncodeHintType, Integer> hints = new Hashtable<>();
        hints.put(EncodeHintType.MARGIN, 1); //设置二维码空白边框的大小 1-4,1是最小 4是默认的国标

        //生成矩阵
        bitMatrix = new MultiFormatWriter().encode(new String(q.getContent().getBytes("UTF-8"),"iso-8859-1"),
                BarcodeFormat.QR_CODE, q.getWidth(), q.getHeight(), hints);  

        //存储路径
        Path path = FileSystems.getDefault().getPath(q.getFilePath(), q.getFileName()); 

        //矩阵颜色设置
        MatrixToImageConfig config = new MatrixToImageConfig(q.getOnColor(), q.getOffColor());

        BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix, config);

        if(null == logoPath){   //不需要中心logo
        	ImageIO.write(image, q.getFormat(), new File(path.toString()));
        }else{
        	this.overlapImage(image, path.toString(), logoPath, q.getFormat());
        }

        System.out.println("success");

    }

(3) 在二维码中心加入logo

	/**
	 * 对生成的二维码添加中心图形
	 * @param image
	 * @param imgSavePath
	 * @param logoPath
	 * @param format
	 */
	public void overlapImage(BufferedImage image, String imgSavePath, String logoPath, String format) {
		try {
			BufferedImage logo = scale(logoPath, image.getWidth() / 5,
					image.getHeight() / 5, true);
			Graphics2D g = image.createGraphics();
			//logo宽高
			int width = image.getWidth() / 5;
			int height = image.getHeight() / 5;
			//logo起始位置,此目的是为logo居中显示
			int x = (image.getWidth() - width) / 2;
			int y = (image.getHeight() - height) / 2;
			g.drawImage(logo, x, y, width, height, null);
			g.dispose();
			ImageIO.write(image, format, new File(imgSavePath));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

(4) 将原始图像缩放至合适尺寸

	/**
	 * 把传入的原始图像按高度和宽度进行缩放,生成符合要求的图标
	 * @param srcImageFile  源文件地址
	 * @param height        目标高度
	 * @param width         目标宽度
	 * @param hasFiller     比例不对时是否需要补白:true为补白; false为不补白;
	 * @throws IOException
	 */
	private static BufferedImage scale(String srcImageFile, int height,
			int width, boolean hasFiller) throws IOException {
		double ratio = 0.0; // 缩放比例
		File file = new File(srcImageFile);
		BufferedImage srcImage = ImageIO.read(file);
		Image destImage = srcImage.getScaledInstance(width, height,
				BufferedImage.SCALE_SMOOTH);
		// 计算比例
		if ((srcImage.getHeight() > height) || (srcImage.getWidth() > width)) {
			if (srcImage.getHeight() > srcImage.getWidth()) {
				ratio = (new Integer(height)).doubleValue()
						/ srcImage.getHeight();
			} else {
				ratio = (new Integer(width)).doubleValue()
						/ srcImage.getWidth();
			}
			AffineTransformOp op = new AffineTransformOp(
					AffineTransform.getScaleInstance(ratio, ratio), null);
			destImage = op.filter(srcImage, null);
		}
		if (hasFiller) {// 补白
			BufferedImage image = new BufferedImage(width, height,
					BufferedImage.TYPE_INT_RGB);
			Graphics2D graphic = image.createGraphics();
			graphic.setColor(Color.white);
			graphic.fillRect(0, 0, width, height);
			if (width == destImage.getWidth(null))
				graphic.drawImage(destImage, 0,
						(height - destImage.getHeight(null)) / 2,
						destImage.getWidth(null), destImage.getHeight(null),
						Color.white, null);
			else
				graphic.drawImage(destImage,
						(width - destImage.getWidth(null)) / 2, 0,
						destImage.getWidth(null), destImage.getHeight(null),
						Color.white, null);
			graphic.dispose();
			destImage = image;
		}
		return (BufferedImage) destImage;
	}

4. 二维码的解码

	 /**
	 * 解析图像
	 * @param  filePath  二维码存放路径
	 * @throws IOException
	 * @throws NotFoundException
	 */
	 public void decode(String filePath) throws IOException, NotFoundException {
	     BufferedImage image;

	     image = ImageIO.read(new File(filePath));
         LuminanceSource source = new BufferedImageLuminanceSource(image);
         Binarizer binarizer = new HybridBinarizer(source);
         BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
         Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
         hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
         Result result = new MultiFormatReader().decode(binaryBitmap, hints);// 对图像进行解码  

         System.out.println("图片中内容:  ");
         System.out.println(result.getText());
     }

5. 生成二维码的示例

package com.Lin;

import java.io.IOException;

import com.google.zxing.NotFoundException;
import com.google.zxing.WriterException;

public class Test {

	public static void main(String[] args) throws WriterException, IOException, NotFoundException {
		TestQrcode t = new TestQrcode();

		//二维码数据的封装,便于以后数据与业务逻辑的分离
		Qrcode q = new Qrcode();
		q.setContent("我多么想和你见一面");
		q.setFilePath("D://");
		q.setFileName("1.png");
		q.setHeight(200);
		q.setWidth(200);
		q.setFormat("png");
		q.setOnColor(0xFF4169E1);   //Royal blue
		String logoPath = "D://1.jpg";

		t.encode(q, logoPath);
//		t.decode("D://1.png");
	}

}

Zxing和j2se的jar包、项目代码及应用例子在github

生成的二维码效果:

时间: 2024-10-10 14:34:30

二维码的功能、特点及使用Java生成带logo的二维码的相关文章

Java生成带logo 的二维码

这个工具类主要实现了两点功能: 1. 生成任意文链接的二维码. 2. 在二维码的中间加入图像. 主要实现步骤: 第一步: 导入QR二维码3.0 版本的core包和一张jpg图片(logo). core包下载地址:http://central.maven.org/maven2/com/google/zxing/core/3.0.0/ 第二步: 新建一个Java project.将刚下载的core-3.0.0 jar 添加到项目依赖中. 具体步骤: 第三步: 新建两个类,分别是: BufferedI

java生成带logo的二维码,自定义大小,logo路径取服务器端

package com.qishunet.eaehweb.util; import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Shape; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import jav

PHP在线生成带LOGO的二维码

PHP生成二维码的实例程序,网上有很多二维码生成程序,不过都是生成标准的二维码,最近的一个项目要求生成中间是小图标(LOGO)的二维码,后经不断查询资料,终于做出来了,主要核心是使用了国外的一个开源类库--QRCODE,生成确实方便,希望能为大家提供一份参考. 使用注意:在生成带lOGO的二维时:1.请将需要显示在二维码中的LOGO图像命名为emwlogo.gif,格式:gif,放在与ewmlogo.php文件同级的目录下2.请在文本框中输入正确的网址,若网址格式不对,则生成的二维码无效. 在线

C# ZXing.Net生成二维码、识别二维码、生成带Logo的二维码(一)

一.ZXing.Net 源代码地址:http://zxingnet.codeplex.com/ 也可以使用Nuget包管理,添加如图: 说明:ZXing是一个开源Java类库用于解析多种格式的1D/2D条形码.目标是能够对QR编码.Data Matrix.UPC的1D条形码进行解码. 其提供了多种平台下的客户端包括:J2ME.J2SE和Android.现在也有了对应的.Net版本 二.生成二维码 将字符编码时可以指定字符格式:默认为ISO-8859-1英文字符集,但一般移动设备常用UTF-8字符

涛哥的Python脚本工具箱之生成带Logo的二维码

近期须要在二维码上加Logo,网上没有找到好用的,于是自己用python写了一个. 须要安装qrcode,PIL库 二维码简称 QR Code(Quick Response Code),学名为高速响应矩阵码,是二维条码的一种.由日本的 Denso Wave 公司于 1994 年发明. 现随着智能手机的普及.已广泛应用于寻常生活中,比如商品信息查询.社交好友互动.网络地址訪问等等. 安装 Python 的二维码库 -- qrcode pip install qrcode 因为生成 qrcode 图

.NET生成带Logo的二维码

使用ThoughtWorks.QRCode生成,利用这个库来生成带Logo的二维码(就是中间嵌了一个图片的二维码),直接见代码: HttpContext context = HttpContext.Current; String data = "二维码的内容";//如果是链接会跳转 if (!string.IsNullOrEmpty(data)) { QRCodeEncoder encoder = new QRCodeEncoder(); Bitmap imgBack = encode

Java实现带logo的二维码

Java实现带logo的二维码 二维码应用到生活的各个方面,会用代码实现二维码,我想一定是一项加分的技能.好了,我们来一起实现一下吧. 我们实现的二维码是基于QR Code的标准的,QR Code是由日本Denso公司于1994年研制的一种矩阵二维码符号码,全称是Quick Response Code QR Code:专利公开,支持中文: QR Code与其他二维码相比,具有识读速度快.数据密度大.占用空间小的优势: 纠错能力: L级:约可纠错7%的数据码字 M级:约可纠错15%的数据码字 Q级

PHP生成带logo图像二维码的两种方法

本文主要和大家分享PHP生成带logo图像二维码的两种方法,主要以文字和代码的形式和大家分享,希望能帮助到大家. 一.利用Google API生成二维码Google提供了较为完善的二维码生成接口,调用API接口很简单,以下是调用代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 $urlToEncode="http://www.php.cn"; generateQRfromGoogle($urlToEncode); /**

生成带logo的二维码

一,生成带log的二维码 1)生成的二维码是流返回,或者是直接写到指定文件夹 二,准备资料 1)引入jar包 <!-- https://mvnrepository.com/artifact/com.google.zxing/core --> <!-- 二维码生成器 --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId&g