基于opencv的二维码图片的生成

前言

之前的文章中,已经实现了数据层面上的二维码的生成,但实际上这并不能实际应用在各种场景之中。而这篇文章就是其从数据到应用的场景之一。

原理

根据之前的文章,我们可以得到二维码位图的边长,而为了转化为图片,我们需要知道二维码图片的像素大小;而为了知道二维码图片的像素大小,就需要知道一个位图的点的像素大小为多少。

QRCode qr("csdn-lisenlingood");
size_t len = qr.getLen(),pixlen = len * pix_size;

在opencv之中,常用于图片生成的有"cv::Mat::ones",其可以生成全白的图片,像素大小为二维码图片像素大小加上边框的空余(可为0)

// CV_32F为选择的图片格式,这便于我们设置图片中的某个像素点为黑色,而RGB模式需要分别设置RGB的值
// 后续需要进行转换到RGB模式的图片上
cv::Mat img = cv::Mat::ones(pixlen + margin * 2, pixlen + margin * 2, CV_32F);

在设置完成空白图片之后,就需要对图片进行“涂黑”处理了。

在处理过程中,需要考虑怎么“涂黑”一个位图的点,假设我们有一个需要涂黑的点,其像素大小为4,那么可以想象得到一个黑色的、边长为4的正方形。假设其在位图的(i,j)点上,也就是在图片的(i * pix_size + margin,j * pix_size + margin)点上,那么有
因此有

for (size_t k = 0; k < pix_size; k++)
		for (size_t l = 0; l < pix_size; l++)
			img.at<float>(i * pix_size + k + margin, j * pix_size + l + margin) = 0;

在此之上,对所有位图点遍历画图有


	for (int i = 0; i < len; i++)
		for (int j = 0; j < len; j++)
			if (qr.get(i, j))
				for (size_t k = 0; k < _pix_size; k++)
					for (size_t l = 0; l < _pix_size; l++)
						img.at<float>(i * _pix_size + k + _margin, j * _pix_size + l + _margin) = 0;

画完图之后,进行转换之后输出,有

qrm.convertTo(res, CV_8U, 255.0);
cv::imwrite("qrcode.png", img);

附录

上述内容以函数进行解释得到

cv::Mat qr2png(QRCode& _qr, size_t _pix_size,size_t _margin)
{
	int len = _qr.getLen(),pixlen = len * _pix_size;
	cv::Mat qrm = cv::Mat::ones(pixlen + _margin * 2, pixlen + _margin * 2, CV_32F), res;

	for (int i = 0; i < len; i++)
		for (int j = 0; j < len; j++)
			if (_qr.get(i, j))
				for (size_t k = 0; k < _pix_size; k++)
					for (size_t l = 0; l < _pix_size; l++)
						qrm.at<float>(i * _pix_size + k + _margin, j * _pix_size + l + _margin) = 0;

	qrm.convertTo(res, CV_8U, 255.0);
	cv::imwrite("qrcode.png", res);
	return res;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值