基于ZXing.NET实现的二维码生成和识别客户端
一、前言
ZXing.Net的一个可移植软件包,是一个开源的、多格式的1D/2D条形码图像处理库,最初是用Java实现的。已经过大量优化和改进,它已经被手动移植。它与.Net 2.0、.Net 3.5、.Net 4.x、.Net 5.x、.Net 6.x、.Net 7.x、Windows RT类库和组件、UWP、.Net Standard 1.x和2.0x、.Net Core App 3.x、Silverlight 4、Silverlight 5、Windows Phone 7.x和Windows Phone 8.x以及Xamarin.Android兼容。
二、项目环境和搭建
项目框架:.NET Framework 4.6.1
项目依赖:ZXing.Net

项目结构和界面设计:

三、实现核心代码
ZXing帮助类
/// <summary>
/// ZXing.NET 二维码帮助类
/// </summary>
public class ZXingHelper
{
/// <summary>
/// 站点二维码的目录
/// </summary>
private static string QRCodeDirectory = "QRCode";
/// <summary>
/// 使用zxing动态库生成二维码
/// </summary>
/// <param name="conetnt">二维码内容</param>
/// <param name="errorMessage">异常信息</param>
/// <param name="logoPath">logo图片路径,默认为空。为空时生成的二维码不带logo</param>
/// <param name="height">二维码图片高度,默认240 单位 pixels</param>
/// <param name="width">二维码图片宽度,默认240 单位 pixels</param>
/// <param name="margin">二维码图片边距,默认为0</param>
/// <returns></returns>
public static Bitmap GenerateQRCode(string conetnt, out string errorMessage, string logoPath = "", int height = 240, int width = 240, int margin = 0)
{
errorMessage = string.Empty;
try
{
BarcodeWriter barCodeWriter = new BarcodeWriter();
barCodeWriter.Format = BarcodeFormat.QR_CODE;
barCodeWriter.Options.Hints.Add(EncodeHintType.CHARACTER_SET, "UTF-8");
barCodeWriter.Options.Hints.Add(EncodeHintType.ERROR_CORRECTION, ZXing.QrCode.Internal.ErrorCorrectionLevel.H);
barCodeWriter.Options.Height = height;
barCodeWriter.Options.Width = width;
barCodeWriter.Options.Margin = margin;
BitMatrix bm = barCodeWriter.Encode(conetnt);
Bitmap qrCodeImage = barCodeWriter.Write(bm);
if (!string.IsNullOrEmpty(logoPath))
{
// 添加Logo
Bitmap logo = new Bitmap(logoPath);
int logoSize = (int)(qrCodeImage.Width * 0.2); // Logo大小为二维码大小的1/5
int logoX = (qrCodeImage.Width - logoSize) / 2;
int logoY = (qrCodeImage.Height - logoSize) / 2;
Graphics qrGraphics = Graphics.FromImage(qrCodeImage);
qrGraphics.DrawImage(logo, new Rectangle(logoX, logoY, logoSize, logoSize));
}
return qrCodeImage;
}
catch (Exception ex)
{
errorMessage = $"Exception raised when generating QRCode,, Exception;{ex}";
return null;
}
}
/// <summary>
/// 使用zxing动态库解析:二维码,条形码......
/// </summary>
/// <param name="image">二维码图像</param>
/// <returns></returns>
public static string ParseBarCode(Bitmap image)
{
BarcodeReader reader = new BarcodeReader();
Result result = reader.Decode(image);
return result.Text;
}
/// <summary>
/// 使用zxing动态库生成二维码
/// </summary>
/// <param name="conetnt">二维码内容</param>
/// <param name="logoPath">logo图片路径,默认为空。为空时生成的二维码不带logo</param>
/// <param name="height">二维码图片高度,默认240 单位 pixels</param>
/// <param name="width">二维码图片宽度,默认240 单位 pixels</param>
/// <param name="margin">二维码图片边距,默认为0</param>
/// <returns></returns>
public static void GenerateQRCode(string conetnt, string logoPath = "", int height = 240, int width = 240, int margin = 0)
{
try
{
BarcodeWriter barCodeWriter = new BarcodeWriter();
barCodeWriter.Format = BarcodeFormat.QR_CODE;
barCodeWriter.Options.Hints.Add(EncodeHintType.CHARACTER_SET, "UTF-8");
barCodeWriter.Options.Hints.Add(EncodeHintType.ERROR_CORRECTION, ZXing.QrCode.Internal.ErrorCorrectionLevel.H);
barCodeWriter.Options.Height = height;
barCodeWriter.Options.Width = width;
barCodeWriter.Options.Margin = margin;
BitMatrix bm = barCodeWriter.Encode(conetnt);
Bitmap qrCodeImage = barCodeWriter.Write(bm);
if (!string.IsNullOrEmpty(logoPath))
{
// 添加Logo
Bitmap logo = new Bitmap(logoPath);
int logoSize = (int)(qrCodeImage.Width * 0.2); // Logo大小为二维码大小的1/5
int logoX = (qrCodeImage.Width - logoSize) / 2;
int logoY = (qrCodeImage.Height - logoSize) / 2;
Graphics qrGraphics = Graphics.FromImage(qrCodeImage);
qrGraphics.DrawImage(logo, new Rectangle(logoX, logoY, logoSize, logoSize));
}
string qrCodeFile = AppDomain.CurrentDomain.BaseDirectory + QRCodeDirectory + "/" + "qrcode.jpg";
if (File.Exists(qrCodeFile))
{
File.Delete(qrCodeFile);
}
qrCodeImage.Save(qrCodeFile, System.Drawing.Imaging.ImageFormat.Jpeg);//保存二维码图片
}
catch (Exception ex)
{
}
}
}
选择logo
/// <summary>
/// 选择logo
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_selectlogo_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);//初始路径为桌面
openFileDialog.Filter = "Logo图片|*.png;*.jpg;*.jpeg;*.ico";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
picLogo.Image = Image.FromFile(openFileDialog.FileName);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
生成二维码
/// <summary>
/// 生成二维码
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void bt_generate_Click(object sender, EventArgs e)
{
try
{
string errorMsg = "";
string content = rtbQRCodeContent.Text;
if (string.IsNullOrWhiteSpace(content))
{
MessageBox.Show("二维码内容不能为空!");
return;
}
picQRCode.Image = ZXingHelper.GenerateQRCode(content, out errorMsg);
if (!string.IsNullOrWhiteSpace(errorMsg))
{
MessageBox.Show(errorMsg);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
识别二维码
/// <summary>
/// 识别二维码
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_identityQrCode_Click(object sender, EventArgs e)
{
try
{
if (picQRCode.Image == null)
{
MessageBox.Show("请先生成二维码!");
return;
}
Bitmap Imagemap = new Bitmap(picQRCode.Image);
string QRCodeResult = ZXingHelper.ParseBarCode(Imagemap);
rtbQRCodeResult.Text = QRCodeResult;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
保存二维码
/// <summary>
/// 保存二维码
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_save_Click(object sender, EventArgs e)
{
try
{
if (picQRCode.Image == null)
{
MessageBox.Show("请先生成二维码!");
return;
}
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "保存图片|*.png;*.jpg;*.jpeg";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
picQRCode.Image.Save(saveFileDialog.FileName, ImageFormat.Png);
MessageBox.Show("保存成功!");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
四、实现演示
五、源码工具获取
关注公众号,后台回复关键字:二维码工具
基于ZXing.NET实现的二维码生成和识别客户端的更多相关文章
- Python 实现二维码生成和识别
今天突然想给自己自己做个头像,然后还是二维码的形式,这样只要扫一扫就可以访问我的主页.然后就开始自己的苦逼之路... 其实实现二维码java,c#,C++等都可以实现:由于自己正在学python,所以 ...
- Android 二维码 生成和识别(附Demo源码)
今天讲一下目前移动领域很常用的技术——二维码.现在大街小巷.各大网站都有二维码的踪迹,不管是IOS. Android.WP都有相关支持的软件.之前我就想了解二维码是如何工作,最近因为工作需要使用相关技 ...
- Android 二维码 生成和识别(转)
原博客地址 :http://www.cnblogs.com/weixing/archive/2013/08/28/3287120.html 还有几个写的也可以参考一下:http://www.itnos ...
- 玩转Android之二维码生成与识别
二维码,我们也称作QRCode,QR表示quick response即快速响应,在很多App中我们都能见到二维码的身影,最常见的莫过于微信了.那么今天我们就来看看怎么样在我们自己的App中集成二维码的 ...
- 【转】Android 二维码 生成和识别(附Demo源码)--不错
原文网址:http://www.cnblogs.com/mythou/p/3280023.html 今天讲一下目前移动领域很常用的技术——二维码.现在大街小巷.各大网站都有二维码的踪迹,不管是IOS. ...
- python qrcode二维码生成与识别
二维码 二维码生成 1.用法 https://github.com/lincolnloop/python-qrcode 2.使用 简单实用 import qrcode # 二维码内容 data = & ...
- iOS二维码生成与识别
在 IOS7 以前,在IOS中实现二维码和条形码扫描,有两大开源组件 ZBar 与 ZXing. 总结下各自的缺点: ZBar在扫描的灵敏度上,和内存的使用上相对于ZXing上都是较优的,但是对于 & ...
- iOS二维码生成、识别、扫描等
二维码扫描 前言: 最近的项目中使用到了二维码,二维码这个模块功能也完成:觉得还是有必要总结一下用来做记录.好长时间没有写二维码了都忘记在差不多了,重新拾起来还是挻快的. 二维码使用场景: 生活中有很 ...
- java利用Google Zxing实现 二维码生成与解析
1.引入zxing 2.使用下面两个类:QRCodeUtil.java和BufferedImageLuminanceSource.java 3.新建单元测试类 复制下面测试代码即可. 1.pom文件中 ...
- java二维码生成-谷歌(Google.zxing)开源二维码生成学习及实例
java二维码生成-谷歌(Google.zxing)开源二维码生成的实例及介绍 我们使用比特矩阵(位矩阵)的QR码编码在缓冲图片上画出二维码 实例有以下一个传入参数 OutputStream ou ...
随机推荐
- 【LeetCode摩尔投票】有趣的简单题:数组中出现次数超过一半的数字
数组中出现次数超过一半的数字 https://leetcode.cn/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-l ...
- 发布一个Visual Studio 2022 插件,可以自动完成构造函数依赖注入代码
赖注入(DI)在开发中既是常见的也是必需的技术.它帮助我们优化了代码结构,使得应用更加灵活.易于扩展,同时也降低了各个模块之间的耦合度,更容易进行单元测试,提高了编码效率和质量.不过,手动注入依赖项也 ...
- ArrayList按指定大小分割集合
ArrayList按指定大小分割集合 项目中使用SpringDataJpa的使用,用到了批量操作,发现框架本身有限制,长度不能超过1000,所以就百度了一下,网上都说是分段处理,也有说用OR的,但数据 ...
- 使用 vscode 远程登陆自己的电脑/服务器 (不需要内网穿透 😇)
问题背景 最近有远程调试的需求,从笔记本连入配置比较高的电脑(windows)运行代码,查阅资料后,了解到大致就是两个方法: 共享屏幕远程控制,如 to desk, 向日葵 内网穿透 + ssh 第一 ...
- 语音合成技术汇总1:Glow-TTS:通过单调对齐实现文本到语音的生成流
今天开始开一期语音合成经典论文的翻译 Glow-TTS:通过单调对齐实现文本到语音的生成流 摘要: 最近,文本到语音(Text-to-Speech,TTS)模型,如FastSpeech和ParaNet ...
- Uncaught TypeError: Failed to set the 'currentTime' property on 'HTMLMediaElement': The provided double value is non-finite.
musicSeekTo: function(value){this.audio.currentTime = this.audio.duration*value; }, musicVoiceSeekTo ...
- 记一次线上问题 → Deadlock 的分析与优化
开心一刻 今天女朋友很生气 女朋友:我发现你们男的,都挺单纯的 我:这话怎么说 女朋友:脑袋里就只想三件事,搞钱,跟谁喝点,还有这娘们真好看 我:你错了,其实我们男人吧,每天只合计一件事 女朋友:啥事 ...
- DXP TreeList 目录树
DXP TreeList 目录树 1.需求背景 需要一个支持勾选,拖动节点,保存各节点顺序的目录树. 2.创建目录树 在treeList控件中添加两个colunm 用来显示绑定数据和显示值. 接下来对 ...
- 手写promise之分步解析
promise是es6推出适用于异步请求的构造函数,帮助解决回调地狱的问题,以下内容将自定义实现promise,只包括基本使用,所以一些边界情况考虑没有在内. 如果对promise用法还不熟悉的朋友可 ...
- [ABC140F] Many Slimes
2023-02-13 题目 题目传送门 翻译 翻译 难度&重要性(1~10):6 题目来源 AtCoder 题目算法 贪心 解题思路 用了两个 multiset a 和一个 set s,一个 ...