QR 二维码中插入图片实现方法
作者:skyYangpan 发布时间:2023-01-24 14:32:32
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比较合适,既满足了图片的清晰度,又不影响二维码的加密数据。
小图片最好居中放置,而且形状可以不规则。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


猜你喜欢
- 一、垃圾回收机制创建对象就会占据内存,如果程序在执行过程中不能再使用某个对象,这个对象是徒耗内存的垃圾。作为程序员不用关心回收垃圾对象问题,
- Hadoop环境搭建详见此文章https://www.jb51.net/article/33649.htm。我们已经知道Hadoop能够通过
- WPF实现滚动条还是比较方便的,只要在控件外围加上ScrollViewer即可,但美中不足的是:滚动的时候没有动画效果。在滚动的时候添加过渡
- 手机二维码扫码登录已经成为了现代互联网时代的一种普遍的登录方式。它的出现,极大地方便了用户登录的流程,减少了用户输入用户名和密码的麻烦。在二
- 顺序语句顺序顾名思义就是程序自上而下执行public class User { public static voi
- 背景项目中用到了多数据源,不同的数据源根据业务不同配置在不同的工程中,由maven来统一聚合。但是前几天在开发过程中突然发现项目前台工程的事
- 目录1、前言2、实例1、前言法存取数据。除此之外,还可以控制数据的存取方式。在面向对象编程中,大多数都是以类作为数据封装的基本单位。类将数据
- 线程组我们可以把线程归属到某个线程组中,线程组可以包含多个线程以及线程组,线程和线程组组成了父子关系,是个树形结构,如下图:使用线程组可以方
- 前言spring 对bean的创建过程做了很完整的封装。但是提供了非常多的扩展接口,供我们使用。这一节主要是实现spring提供的获取 be
- 本文描述了TCP协议,首先简单介绍了TCP完成了一些什么功能;介绍了TCP报文格式,以及典型报文的数据格式;接着从链路控制和数据传输两个方面
- 本文实例为大家分享了Unity实现俄罗斯方块第3部分,供大家参考,具体内容如下解决穿透问题逻辑部分1、在物体进行移动的过程中更新格子的信息,
- 零、学习目标1、掌握application.properties配置文件2、掌握application.yaml配置文件3、掌握使用@Con
- string str="aaa|||bbb|||ccc"; string[] sArray=str.Split(new[
- 为什么需要ThreadLocalRandomjava.util.Random一直都是使用比较广泛的随机数生成工具类,而且java.lang.
- 简介在Spring 5中,Spring MVC引入了webFlux的概念,webFlux的底层是基于reactor-netty来的,而rea
- 目录文件下载文件上传 * * 的配置多个 * 的执行顺序异常处理器基于配置的异常处理基于注解的异常处理总结文件下载使用ResponseEn
- 本文主要探讨以下几个问题:嵌套滑动设计目的嵌套滑动的实现嵌套滑动与事件分发机制嵌套滑动设计目的不知道大家有没有注意过淘宝APP首页的二级联动
- 在Flutter开发过程中,我门有时候需要对一些数据进行本地的持久化存储,使用sp文件形式虽然也能解决问题,但是有时数据量较大的时候,显然我
- volatilevolatile是一种轻量同步机制。请看例子MyThread25类public class MyThread25 exten
- 这篇文章主要介绍了springboot整合通用mapper过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价