QRcode 二维码中插入图像分析
本文为翻译文章,英文原文请看这里[link],文中的QRcode中插入图片方法并非简单的利用容错,可以在保证识别正确率的同时加入非常大块的图像,文字等。正文如下————
QRcode是一种用来对字节符号进行编码的二维码。它的最常用方法之一便是在手机上替代网址的手动输入,而采用扫描带有网址信息的QRcode来打开相应的URL地址(常见的比如广告海报,不常见的比如飞机后面的条幅[link],GEEK的比如谷歌地图所看到的屋顶[link],2B的比如在自己衣服上裤子上[link][link]等等)
QRcode采用里德-所罗门码来进行编码,里德-所罗门码是一种带有容错机制的编码方法,采用这种机制扫描的时候并不需要读取所有的比特位,因此也使得简单的在QRcode中少量的更改信息,比如加入小型的图片等等,成为了可能。举个例子,2008年的时候Duncan Robertson为BBC电视台制作了一幅QRcode图片,就是用到了其强大的容错能力。
这是一种很简单但又非常实用的技巧,但是,站在技术的角度来看会感到很乏味。尽管上面的BBC三个大字看起来是很像一个QRcode里的字节符,但它对于QRcode的解码所带来的,仅仅是错误信息的冗余而已。我们可以把BBC三个字符处换成任何字符甚至图片,他们之间的唯一区别仅仅是带来的不同噪声而已。
在这个BBC QR Logo出来之后,网上出现了相当多的模仿者,大部分和上面一样,只是把中间的字符换成自己所喜爱的噪声信号。比如这幅迪斯尼海报就是代表[link]。
其实要说的是,对于我们技术工作者来说,有其他更好的方法来制作包含自己图像的QRcode,而不是仅仅添加一些无聊的噪声,和依靠QRcode的容错率来得到一个相对稳定的二维码。就比如下面这些:
这篇文章所要解释的就是制作这种二维码背后所包含的数学原理,也包括其简单的制作方法。文中所用到的源码发布在code.google.com/p/rsc上,并且还制作了一个在线的转换网站[link]。
上图中彩色部分就是编好的里德-所罗门码。对于每一副图像来说,可能含有一块或者多块里德-所罗门编码块,这个是由图像大小以及设定的纠错能力来决定的。对于下图来说,不同的编码块对应不同的颜色,L编码方式对应最小的错误冗余,为20%,其余的三种则分别增加冗余码,对应的百分比为38%,55%,和65%。
(实际上,我们可以通过读取图像最左上角的两个象素点来判断编码的冗余程度。定义黑色为0,白色为1,那么如果看到00则是L级别的冗余,01是M,10是Q,11则是最高的H级别冗余。现在,我们可以通过这种方法判断这幅印在T恤上的QR码[link]知道它所用的是最高级别的冗余,而另外的一件[link]比较2B的则用的是最少的冗余,以至于难以甚至无法读取)
正如我上面所提到的一样,原码信息是被显式的包含在被编码的图像中的,这样,原码信息中的每一个比特就与QR图像中的每一个像素所对应。这些像素在上面的图像中对应非灰色的色彩部分,灰色部分则是用于纠错的冗余信息码。编码好的比特是按照Z字形的结构连续排列在图像中的每一个像素上,从左下角开始并在右下角结束,如下图:
有了上面的这些工作,我们可以非常容易的知道原码信息在图像中的位置。然后通过改变自己的原码信息,就可以改变图像中的像素以至于可以在里面作图了。虽说如此,下面的一些情形可以让事情变得更有趣。
QR Masks
第一个难点就是编码完成的数据会按照下面的几个模板来异或运算进行混淆,混淆过后才是最终得到的图像。这样的模板有8个
对于一个QR编码器来说,它会根据输入的数据情况来选择最合适的模板来进行混淆,使得原本的数据隐藏起来。但在我们的这个编码器中,我们可以先选择好模板,然后再决定设计输入的数据。虽然说与原本的设计模式相违背,但依然可以产生合法的代码。
QR Code编码
第二个难点就是我们想要制作的是含有容易理解的信息的QRcode。简单来说你可以随意的按照自己设计的图片来生成QRcode,但这样解码出来的数据就完全是杂乱无章的乱码,作为一副QR图像来说就毫无意义了。因此我们需要约束自己的图案,以求产生包含能理解的内容的QRcode。幸运的是,QRcode允许原码信息以一些符号来表示,其中一种是一个8比特的数据,它需要引入一些垃圾数据来生成一副图像。另一种则是数值数据,这种格式中每10个比特表示3个十进制字符。到这里,制作特定图像中的限制已经很明显了,我们不能生成值超过999的10比特数据(注:10比特二进制最大值为1023)。尽管不能完全按照我们想要的来,但其灵活性已经很高了,能使用的比特串达到所有比特串的99.6%。因此,在生成自己想要的图片后,如果发现解码错误,我们随机选5个最具代表性的值为1的比特位——只有1才能产生错误的比特码——然后直接改写成0,重复扫描和以上的步骤。
但是仅仅有数字数据并不是一件有趣的事,我们扫描QR码只能得到一个毫无意义的巨大的十进制数值。又一次幸运的是,QRcode允许在一条信息中采用多种不同的编码类型。因此我就制作了这样的一条信息,前面一部分是自己的网址信息,然后再在一个#符号后面插入用来作图的数值数据。
http://swtch.com/pjw/#123456789…
数据前面的URL最先被编码,它在QR图像中占据最左边的部分,然后整个数据的冗余被加到编码数据的尾部,它占据了QR图像最右边的部分。中间的部分就是我们自己预先设定好的图像比特数据。
当使用手机扫描这幅QR图像的时候,解码器识别出URL并在浏览器中打开这个地址,然后根据其后#处的数值跳到页面相应的游标处。当然,这样的游标是不存在的,即便这样浏览器也不会发出任何抱怨。
使用这样的方法产生的图像如下:
制作过程的第三个难点是,如何才能将想要的图像均匀的平铺在QRcode中,而不是前面的那种仅仅显示在中间的一小块。再次幸运的是,这一点我们仍然可以做到。
没有填写的部分都代表比特位为0。灰色部分就是我们可以自己完全控制的比特部分,白色部分则是尾随后面的纠错冗余码。由上面的异或特性我们知道,我们可以将编完码的结果和上面的这组基进行异或,而不改变其他的控制位,并且保持冗余码的更新。
可能你又要抱怨了,这种做法其实无所事事,我们的图像位置该在哪儿还是在哪儿,没起到作用。
请等我慢慢说完,在有了上面知识的基础上,我们可以通过把多个基组合起来,以达到将自己的数据和容错码中的数据交换的目的。虽然说在根本上我们不能增加可以自由控制的点的数目,但却可以移动可以自由控制的点的位置——也就是说达到将不可控点空间分散化的效果,将这些不合作的控制点对图像整体的影响降低。这其实就是小标题中高斯-约旦消元法的基本思想,从原矩阵中产生一个简化的行列式。
上面的这个矩阵给了我们一个重要提示,即是没法做到完全一般化。尽管这些比特串是完全相互独立的,但是由于同时还需要照顾不守规矩的错误冗余码,我们没法做到QR图像中的每一个像素都是我们想要的值。在这里例子中,比特串最后的四个比特是不可控的,我们所做的操作就是通过上述基来对比特位置重构,分散不可控的点,使最终画面更协调。
在实际的程序里,采用这种思想的一个做法便是对里德-所罗门码块中的每一个比特,根据其在图像中的重要性进行打分与排序(图像中高对比区域像素的得分小于低对比区域像素),然后遍历图像中每一个像素,如果我们的基允许对其的改变并且改变后的得分更高的话,那么用相应的基对他进行异或,否则继续处理下一个像素。
使用这种方法,我们可以得到更宽但噪声更多的QR图像
图片里所示人物的前额以及右半部分的脸就为得到更宽的脑袋而牺牲了。
我们还可以随机决定可控点的位置,然后产生一种雾化的图片效果。
旋转
好了,以上方法介绍完毕之后大家都可以制作差不多凑合的QR图像了。我这里还剩下处理的最后一招,就是QR图像的旋转。在上面的图像里所有没法控制的冗余点部分都存在于存在于QR图像的右侧,但由于QRcode对于图像的旋转没有任何要求,因此其实可以把这部分移动到别的什么地方。
QRcode 二维码中插入图像分析相关推荐
- qrcode二维码生成工具
本篇,笔者介绍下自己用java开发的一款QR码生成器图形化工具. qrcode编码.解码功能依赖于google的二维码开源库google.zxing. 笔者项目github地址: https://gi ...
- js生成二维码以及插入图片
js生成二维码以及插入图片 先根据qrcode官网demo,不同属性值的变化,二维码的变化效果:https://larsjung.de/jquery-qrcode/latest/demo/ 进入dem ...
- QRCode二维码生成方案及其在带LOGO型二维码中的应用(2)
QRCode二维码生成方案及其在带LOGO型二维码中的应用(2) 原文:QRCode二维码生成方案及其在带LOGO型二维码中的应用(2) 续前:QRCode二维码生成方案及其在带LOGO型二维码中的应 ...
- java完整的利用itext5制作pdf、二维码图片插入pdf,并解析pdf中的二维码信息
利用itext5.zxing.QRCore制作pdf.二维码图片插入pdf,并解析pdf中的二维码信息,手机可以实现扫描获取二维码的信息,并进行验证你的解析是否正确. 先是生成二维码图片并插入pdf中 ...
- QRCode二维码生成方案及其在带LOGO型二维码中的应用(1)
提要:很多公司为商业宣传之需,常将企业LOGO加入二维码中,但如果LOGO遮挡区域足够地大,二维码就变得无法识别.那么,有没有一种办法将上述区域预先"抠空"出来(以便专门放置LOG ...
- QRCode二维码生成方案及其在带LOGO型二维码中的应用
很多公司为商业宣传之需,常将企业LOGO加入二维码中,但如果LOGO遮挡区域足够地大,二维码就变得无法识别.那么,有没有一种办法将上述区域预先"抠空"出来(以便专门放置LOGO), ...
- 为什么二维码中可以插入图片?
二维码的生成细节和原理 二维码又称QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据 ...
- java生成与解析二维码 支持插入图片与文字
1.依赖: <!-- https://mvnrepository.com/artifact/com.google.zxing/core --><dependency><g ...
- 如何给二维码动态插入图片
很多用户在制作二维码时,会在二维码中嵌入Logo图片,以突显一些标志性信息.如果是批量制作的二维码,需要给每个二维码嵌入不同的图片,这种情况该如何实现呢?下面,小编就给大家演示二维码动态插入图片的操作 ...
最新文章
- python语音转文字源码_【python3】Python十行代码搞定文字转语音
- js 提交form表单,js更改form表单的action属性
- Linux总线驱动-02: struct bus_type 结构体
- 复制内存时检测到可能的io争用条件_这篇高并发服务模型大科普,内部分享时被老大表扬了...
- JQuery选择器——基本筛选选择器和内容筛选选择器
- 2018年10月Top 10 Python开源项目
- xgboost 多gpu支持 编译
- python基础入门(6)之列表
- 原来如此?修改浏览器滚动条样式
- FPGA同步复位与异步复位深度理解
- 2月18日 Ubuntu 14.04下安装Gazebo(用于仿真)
- Ubuntu - 安装gcc
- 微信小程序开发--uniapp
- 微信语音导出-微信收藏语音导出-微信语音转MP3文件
- [渝粤教育] 广东-国家-开放大学 21秋期末考试组织行为学10068k2
- ASP与JSP的比较
- CeoMax总裁WordPress模板3.8.1免受权版本
- 在AD中设置漫游配置文件与文件夹重定向
- 收费数万元的考研“协议班”藏猫腻,授课质量差,退费老大难
- python时间戳是什么意思_python时间戳是啥意思?