QR 二维码中插入图片实现方法

所属分类: 软件编程 / java 阅读数: 35
收藏 0 赞 0 分享

QR 二维码中插入图片

二维码终于火了,现在大街小巷大小商品广告上的二维码标签都随处可见,而且大都不是简单的纯二维码,而是中间有个性图标的二维码。

我之前做了一个使用google开源项目zxing实现二维码、一维码编码解码的程序并开放了源码(用C#实现的条形码和二维码编码解码器),今天继续在此程序基础上,实现二维码中间加小图片。

背景知识

QRcode使用里德-所罗门码来进行错误修正。对于我们来说,里德-所罗门编码有两个非常重要的特性。第一,它是一种显式系统码,也就是说,你可以在最终的编码中直接看到原有的信息。就好比我们对”hello world”进行编码,最终看到的是”hello world”以及其后面跟随的几个容错码。第二点,里德-所罗门编码是可以被”异或”的,将两个不同里德-所罗门编码得到的结果异或运算后会得到一个新的里德-所罗门码,并且这个新码的原码即是原来两个原码的异或。如果你想知道为什么这两个特性会成立,请看Finite Field Arithmetic and Reed-Solomon Coding.

QRcode

一副QRcode图像会定义一些独特的描述符来帮助人们或者电脑识别出自己是一张QRcode。这种描述符随着QRcode的大小不同而略有区别——越大的QRcode图像拥有越多的描述符。但是对于人的识别来说,特征最明显的还是图片的四个角的符号是固定的,看到这样的四个角人类就本能的反应:这是一个QRcode。

(实际上,我们可以通过读取图像最左上角的两个象素点来判断编码的冗余程度。定义黑色为0,白色为1,那么如果看到00则是L级别的冗余,01是M,10是Q,11则是最高的H级别冗余。

有了上面的这些工作,我们可以非常容易的知道原码信息在图像中的位置。然后通过改变自己的原码信息,就可以改变图像中的像素以至于可以在里面作图了。虽说如此,下面的一些情形可以让事情变得更有趣。

我做的二维码插入图片:

之前我给大家免费提供了使用zxing开源项目改造而成的一二维码编码解码器,但未能插入图片。这次经过一番努力,成功将图片插入二维码,并能编码和解码。插入图片的关键在于二维码容错系数的调整,源码中有详尽描述。

界面:

 

要在二维码中插入图片且可以正常解码,主要注意以下两点即可:

1.设置二维码的容错系数要高;

在Zxing项目中,二维码生成的时候是可以设置容错系数的:

将EncodeHintType.ERROR_CORRECTION设置成ErrorCorrectionLevel.H

//构造二维码写码器
        MultiFormatWriter mutiWriter = new com.google.zxing.MultiFormatWriter();
        Hashtable hint=new Hashtable();
        hint.Add(EncodeHintType.CHARACTER_SET,"UTF-8");
        hint.Add(EncodeHintType.ERROR_CORRECTION,com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.H);
        //生成二维码
        ByteMatrix bm = mutiWriter.encode(txtMsg.Text, com.google.zxing.BarcodeFormat.QR_CODE, 300, 300,hint);
        Bitmap img = bm.ToBitmap();

2.中间插入的图片大小和位置要合适;


中间图片如果太大,遮住了二维码的大部分面积,那肯定不行,如果太小,就起不到个性化的效果。

那么多大合适呢,根据前文中描述的QR码的特点,其三个带方块的角上是数据区,不能覆盖,只有中间和右下角这片区域可以覆盖,但也不宜过大。

经测试,中间小图片尺寸占二维码总宽度的2/7比较合适,既满足了图片的清晰度,又不影响二维码的加密数据。

小图片最好居中放置,而且形状可以不规则。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

更多精彩内容其他人还在看

Java的面向对象编程基本概念学习笔记整理

这篇文章主要介绍了Java的面向对象编程基本概念学习笔记整理,包括类与方法以及多态等支持面向对象语言中的重要特点,需要的朋友可以参考下
收藏 0 赞 0 分享

Eclipse下编写java程序突然不会自动生成R.java文件和包的解决办法

这篇文章主要介绍了Eclipse下编写java程序突然不会自动生成R.java文件和包的解决办法 的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

基于Java实现杨辉三角 LeetCode Pascal's Triangle

这篇文章主要介绍了基于Java实现杨辉三角 LeetCode Pascal's Triangle的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Java中Spring获取bean方法小结

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架,如何在程序中获取Spring配置的bean呢?下面通过本文给大家介绍Java中Spring获取bean方法小结,对spring获取bean方法相关知识感兴趣的朋友一起学习吧
收藏 0 赞 0 分享

如何计算Java对象占用了多少空间?

在Java中没有sizeof运算符,所以没办法知道一个对象到底占用了多大的空间,但是在分配对象的时候会有一些基本的规则,我们根据这些规则大致能判断出来对象大小,需要的朋友可以参考下
收藏 0 赞 0 分享

剖析Java中的事件处理与异常处理机制

这篇文章主要介绍了Java中的事件处理与异常处理机制,讲解Java是如何对事件或者异常作出响应以及定义异常的一些方法,需要的朋友可以参考下
收藏 0 赞 0 分享

详解Java的Struts2框架的结构及其数据转移方式

这篇文章主要介绍了详解Java的Struts2框架的结构及其数据转移方式,Struts框架是Java的SSH三大web开发框架之一,需要的朋友可以参考下
收藏 0 赞 0 分享

Java封装好的mail包发送电子邮件的类

本文给大家分享了2个java封装好的mail包发送电子邮件的类,并附上使用方法,小伙伴们可以根据自己的需求自由选择。
收藏 0 赞 0 分享

在Java的Struts中判断是否调用AJAX及用拦截器对其优化

这篇文章主要介绍了在Java的Struts中判断是否调用AJAX及用拦截器对其优化的方法,Struts框架是Java的SSH三大web开发框架之一,需要的朋友可以参考下
收藏 0 赞 0 分享

java多线程Future和Callable类示例分享

JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。今天我们就来研究下Future和Callab
收藏 0 赞 0 分享
查看更多