如何在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比较合适,既满足了图片的清晰度,又不影响二维码的加密数据。

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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要生成二维码并将其保存到数据库,您可以使用以下步骤: 1. 导入相关的Java库:您可以使用ZXing库来生成二维码。请确保已将其添加到您的Java项目。 2. 生成二维码:使用ZXing库QRCodeWriter类,您可以创建一个QRCode对象,该对象可以转换为图片格式并保存到本地。 3. 将二维码图片转换为字节数组:使用ImageIO类将二维码图片转换为字节数组。 4. 将字节数组保存到数据库:使用JDBC连接到您的数据库,并使用PreparedStatement类将字节数组保存到数据库。 以下是一些示例代码来演示这些步骤: ```java import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Base64; import javax.imageio.ImageIO; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; public class QRCodeGenerator { public static void main(String[] args) throws SQLException { String data = "Hello, world!"; // 数据内容 int size = 300; // 生成二维码图片大小 String format = "png"; // 二维码图片格式 byte[] imageBytes = null; // 生成二维码 QRCodeWriter writer = new QRCodeWriter(); BitMatrix matrix; try { matrix = writer.encode(data, com.google.zxing.BarcodeFormat.QR_CODE, size, size); BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { image.setRGB(x, y, matrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); } } ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(image, format, baos); imageBytes = baos.toByteArray(); } catch (WriterException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } // 将字节数组保存到数据库 Connection conn = null; // 假设您已连接到数据库 PreparedStatement ps = conn.prepareStatement("INSERT INTO qr_codes (data) VALUES (?)"); ps.setBytes(1, imageBytes); ps.executeUpdate(); } } ``` 在这个示例,我们生成一个包含字符串“Hello, world!”的二维码,将其转换为PNG格式的图片,将图片字节数组保存到名为“qr_codes”的数据库表。请注意,此示例仅用于演示目的,您需要根据您的具体需求进行适当的修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值