C#二维码生成与解码(二)
本文内容在《C#二维码生成与解码》的基础上增加了纠错级别和Logo图标加入,增加了二维码的功能。关于透明度在这里没有单独显现,因为在颜色里面就已经包含,颜色值由8位8进制构成,最前面的两位就是控制透明度的,后面的6位分为对应红绿蓝的值。
【窗体效果图】

【程序源代码】
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ZXing;
using ZXing.QrCode.Internal;
using System.IO; namespace ErWeiMa
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
cbocorrection.SelectedIndex = ;
} /// <summary>获取标志图像路径</summary>
private void btnLogo_Click(object sender, EventArgs e)
{
var dlg = new OpenFileDialog()
{
Filter = "图片文件|*.png;*.bmp;*.dib;*.jpg;*.jpeg;*.jpe;*.jfif;*.tif;*.tiff|所有文件|*.*",
Multiselect = false
};
if (dlg.ShowDialog() ==DialogResult.OK)
this.txtLogoFile.Text = dlg.FileName;
} /// <summary>生成二维码图片</summary>
private void btnGen_Click(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(this.txtMessage.Text))
{
MessageBox.Show("编码用的内容字符串不能为空。", "操作错误",MessageBoxButtons.OK,MessageBoxIcon.Error);
return;
} this.imgQrcode.Image = null; try
{
// 纠错级别
var errCorrLvl = ErrorCorrectionLevel.M;
var corrRatio = 0.15;
switch (this.cbocorrection.SelectedIndex)
{
case : errCorrLvl = ErrorCorrectionLevel.L; corrRatio = 0.07; break;
case : errCorrLvl = ErrorCorrectionLevel.M; corrRatio = 0.15; break;
case : errCorrLvl = ErrorCorrectionLevel.Q; corrRatio = 0.25; break;
case : errCorrLvl = ErrorCorrectionLevel.H; corrRatio = 0.30; break;
} int Qsize = Int32.Parse(textBox1.Text);
if(Qsize==)
Qsize=(int)this.imgQrcode.Width;
// 生成 QR Code 位图
var hints = new Dictionary<EncodeHintType, object>();
hints.Add(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.Add(EncodeHintType.ERROR_CORRECTION, errCorrLvl);
var matrix = new MultiFormatWriter().encode(this.txtMessage.Text, BarcodeFormat.QR_CODE,Qsize ,Qsize, hints);
var bitmap = new Bitmap(matrix.Width, matrix.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
var deepColor = ColorTranslator.FromHtml("0xff000000");
var lightColor = ColorTranslator.FromHtml("0xffffffff");
if (!String.IsNullOrWhiteSpace(this.txtDeepColor.Text))
deepColor = ColorTranslator.FromHtml("0x" + this.txtDeepColor.Text.TrimStart('#'));
if (!String.IsNullOrWhiteSpace(this.txtLightColor.Text))
lightColor = ColorTranslator.FromHtml("0x" + this.txtLightColor.Text.TrimStart('#'));
for (int x = ; x < matrix.Width; x++)
for (int y = ; y < matrix.Height; y++)
bitmap.SetPixel(x, y, matrix[x, y] ? deepColor : lightColor); // 添加标志
if (!String.IsNullOrWhiteSpace(this.txtLogoFile.Text))
{
if (File.Exists(this.txtLogoFile.Text))
{
var logo = new Bitmap(this.txtLogoFile.Text);
var ratio = (double)(logo.Width * logo.Height) / (double)(bitmap.Width * bitmap.Height);
if (ratio > corrRatio * 0.6) // 标志图片大小最大只能占到最大容错面积的60%以保证图片高可读性
{
MessageBox.Show(String.Format("在当前指定的纠错级别下,标志图片大小最大只能占到二维码图片面积的 {0:P1}。", corrRatio * 0.6), "操作错误",MessageBoxButtons.OK,MessageBoxIcon.Error);
return;
} CreateQRCodeBitmapWithPortrait(bitmap, logo);
}
else
{
var dlgResult = MessageBox.Show("指定的标志图片文件不存在!\r\n是否忽略标志图片继续生成?", "警告",MessageBoxButtons.YesNo,MessageBoxIcon.Warning);
if (dlgResult == DialogResult.OK) return;
}
}
this.imgQrcode.Image = bitmap;
}
catch (Exception ex)
{
MessageBox.Show(String.Format("生成二维码图片时出错。\r\n错误类型:{0}\r\n错误信息:{1}", ex.GetType(), ex.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
} } /// <summary>在二维码位图上绘制标志。</summary>
private void CreateQRCodeBitmapWithPortrait(Bitmap qrCode, Bitmap logo)
{
Graphics g = Graphics.FromImage(qrCode);
int qsize = Int32.Parse(textBox1.Text);
// 设置头像要显示的位置,即居中显示
int rectX = (qsize- logo.Width) / ;
int rectY = (qsize - logo.Height) / ;
g.DrawImage(logo, rectX, rectY); g.Dispose();
} /// <summary>保存二维码图片 </summary>
private void btnSave_Click(object sender, EventArgs e)
{
Image img = imgQrcode.Image;
if (img != null)
{
SaveFileDialog sFD = new SaveFileDialog();
sFD.Filter = "*.png|*.png";
if (sFD.ShowDialog() == DialogResult.OK)
{
Bitmap bmap = new Bitmap(img, img.Width, img.Height);
bmap.Save(sFD.FileName);
MessageBox.Show("保存成功!");
}
}
else
{
MessageBox.Show("您还没有生成二维码!");
}
} private void btnRead_Click(object sender, EventArgs e)
{
var dlg = new OpenFileDialog()
{
Filter = "图片文件|*.png;*.bmp;*.dib;*.jpg;*.jpeg;*.jpe;*.jfif;*.tif;*.tiff|所有文件|*.*",
Multiselect = false
};
if (dlg.ShowDialog() ==DialogResult.OK)
{
// 采用先将图片文件内容读入字节数组然后再通过该数组创建图像实例是为了读取图片后图片文件不再会被文件访问锁锁定
byte[] bytes = null;
using (var stream = File.Open(dlg.FileName, FileMode.Open))
using (BinaryReader reader = new BinaryReader(stream))
{
var fileInfo = new FileInfo(dlg.FileName);
bytes = reader.ReadBytes(unchecked((int)fileInfo.Length));
reader.Close();
} try
{
MemoryStream ms = new MemoryStream(bytes);
imgQrcode.Image = new Bitmap(ms);
}
catch (Exception ex)
{
this.imgQrcode = null;
MessageBox.Show(String.Format("读取图片信息时出错,可能图片是不认识的图像格式。\r\n错误类型:{0}\r\n错误信息:{1}", ex.GetType(), ex.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
} private void btnAnalysis_Click(object sender, EventArgs e)
{
var image = imgQrcode.Image;
if (image == null)
{
MessageBox.Show("二维码图片空白,还没读取二维码图片。", "操作错误", MessageBoxButtons.OK, MessageBoxIcon.Stop);
return;
} this.txtMessage.Text = String.Empty;
this.lblQ.Text = "(空)"; Bitmap bitmap;
bitmap = new Bitmap(image); try
{
LuminanceSource source = new BitmapLuminanceSource(bitmap);
/*
* 在二值化方面,GlobalHistogramBinarizer 提供了比较基础的二值化方法,而 HybridBinarizer 则算是高级的算法,建议要机器性能比较好才使用。
* HybridBinarizer 在识别对比度比较低的图片就是比 GlobalHistogramBinarizer 要差;
* HybridBinarizer 在光照均匀的情况下,效果比 GlobalHistogramBinarizer 优。
*/
// var binarizer = new ZXing.Common.HybridBinarizer(luminance);
var binarizer = new ZXing.Common.GlobalHistogramBinarizer(source);
var binBitmap = new BinaryBitmap(binarizer);
var hints = new Dictionary<DecodeHintType, object>();
hints.Add(DecodeHintType.CHARACTER_SET, "UTF-8");
var result = new MultiFormatReader().decode(binBitmap, hints);
if (result == null)
{
MessageBox.Show("无法正确解析图片。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
} this.txtMessage.Text = result.Text;
this.lblQ.Text = result.BarcodeFormat.ToString();
}
catch (Exception ex)
{
MessageBox.Show(String.Format("解析图片时出错。\r\n错误类型:{0}\r\n错误信息:{1}", ex.GetType(), ex.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
【引用dll文件】
http://pan.baidu.com/s/1ntNr79v
【关注我的博客】
C#二维码生成与解码(二)的更多相关文章
- Java二维码生成与解码
基于google zxing 的Java二维码生成与解码 一.添加Maven依赖(解码时需要上传二维码图片,所以需要依赖文件上传包) <!-- google二维码工具 --> &l ...
- HTML-DEV-ToolLink(常用的在线字符串编解码、代码压缩、美化、JSON格式化、正则表达式、时间转换工具、二维码生成与解码等工具,支持在线搜索和Chrome插件。)
HTML-DEV-ToolLink:https://github.com/easonjim/HTML-DEV-ToolLink 常用的在线字符串编解码.代码压缩.美化.JSON格式化.正则表达式.时间 ...
- jquery二维码生成插件_二维码生成器
jquery二维码生成插件_二维码生成器 下载地址:jquery生成二维码.rar
- C#实现二维码生成与解码
前几天公司内部分享了一个关于二维码的例子,觉得挺好玩的,但没有提供完整的源码.有时候看到一个好玩的东西,总想自己Demo一个,于是抽空就自己研究了一下. 一.二维码的原理 工欲善其事,必先利其器.要生 ...
- Java二维码生成与解码工具Zxing使用
Zxing是Google研发的一款非常好用的开放源代码的二维码生成工具,目前源码托管在github上,源码地址: https://github.com/zxing/zxing 可以看到Zxing库有很 ...
- 转【微信小程序 四】二维码生成/扫描二维码
原文:https://blog.csdn.net/xbw12138/article/details/75213274 前端 二维码生成 二维码要求:每分钟刷新一次,模拟了个鸡肋,添加了个按分钟显示的时 ...
- C#二维码生成与解码
[窗体效果图] [程序源代码] using System; using System.Collections.Generic; using System.ComponentModel; using S ...
- 主攻ASP.NET.4.5 MVC4.0之重生:二维码生成和谷歌二维码
使用ThoughtWorks.QRCode.Codec 效果图 using ThoughtWorks.QRCode.Codec; 非原创代码 public void code(string id) { ...
- simple go web application & 二维码生成 & 打包部署
go语言简易web应用 & 二维码生成及解码 & 打包部署 转载请注明出处: https://www.cnblogs.com/funnyzpc/p/10801476.html 前言(闲 ...
随机推荐
- 乐在其中设计模式(C#) - 外观模式(Facade Pattern)
原文:乐在其中设计模式(C#) - 外观模式(Facade Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 外观模式(Facade Pattern) 作者:webabcd 介绍 ...
- redis源代码解读之内存管理————zmalloc文件
本文章主要记录本人在看redis源代码的一些理解和想法.由于功力有限,肯定会出现故障,所以.希望高手给出指正. 第一篇就是内存相关的介绍.由于我喜欢先看一些组件的东西,再看总体的流程. 先上一下代码吧 ...
- —教训深刻—SQL Server大约TempDB使用
场景现象 中午查询了流水,因未与业务人员沟通好.忘了删选条件,导致TempDB不能分配空间,SQL Server高负载执行. 错误分析 我们来看看错误日志: 再来看看TempDB自增长记录: 事件 逻 ...
- .net RPC框架选型(一)
近期开始研究分布式架构,会涉及到一个最核心的组件:RPC(Remote Procedure Call Protocol).这个东西的稳定性与性能,直接决定了分布式架构系统的好坏.RPC技术,我们的产品 ...
- OpenCVR 有新成员 OpenCVV OpenCVC
OpenCVC主要负责OpenCVR报名, OpenCVV支持Android IOS Mac Windows 的client 版权声明:本文博客原创文章,博客,未经同意,不得转载.
- Nancy 框架学习
Nancy 框架 1.是一个轻量级用于构建http相应的web框架: 2.与mvc类似,有自己的路由机制: 3.可以处理 DELETE , GET , HEAD , OPTIONS , POS ...
- Repository、IUnitOfWork和IDbContext
DDD 领域驱动设计-谈谈Repository.IUnitOfWork和IDbContext的实践 上一篇:<DDD 领域驱动设计-谈谈 Repository.IUnitOfWork 和 IDb ...
- windows cmd命令行下创建文件和文件夹
在window下无法通过 右键=>新建 命令来创建以点开头的文件和文件夹 比如 .log ,会提示必须输入文件名. 可以通过命令行来创建 新建文件夹 mkdir .vs 新建文件 type NU ...
- [WebGL入门]四,渲染准备
注意:文章翻译http://wgld.org/,原作者杉本雅広(doxas),文章中假设有我的额外说明,我会加上[lufy:].另外.鄙人webgl研究还不够深入,一些专业词语,假设翻译有误,欢迎大家 ...
- Qt on Android: Qt 5.3.0 公布,针对 Android 改进的说明
5月20日本,Qt 官方博客宣布 Qt 5.3.0 公布! 这个版本号聚焦在性能.稳定性和可用性的提升上,与 5.1 / 5.2 相比有非常大提升. 5.3.0 的主要变化: 稳定能.可用性大大提升 ...