使用开源类库ZXing.dll可以在C#中生成二维码和解析二维码为指定的字符串(含url)
新建windows窗体应用程序QRCodeDemo,.net 4.5,将默认的Form1重命名为FormQuickResponseCode。
添加对开源类库zxing.dll和zxing.presentation.dll的引用,用于解析和生成条码【一维条码、二维条码均可生成】。
窗体FormQuickResponseCode设计器如下:
新建读写二维码类QrCodeUtil,QrCodeUtil.cs源程序如下:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZXing;
using ZXing.QrCode;
using ZXing.QrCode.Internal;
namespace QRCodeDemo
{
/// <summary>
/// 文本字符串与二维码图片之间的转换
/// 字符串转二维码 String---->Image
/// 二维码转字符串 Image---->String
/// </summary>
public class QrCodeUtil
{
/// <summary>
/// 将文本字符串转化为二维码图片
/// </summary>
/// <param name="codeContent">打印条码对应的字符串</param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="barcodeFormat">条码格式:CODE_128代表一维条码,QR_CODE代表二维码</param>
/// <param name="margin"></param>
/// <returns></returns>
public static Bitmap GeneateQrCode(string codeContent, int width, int height, BarcodeFormat barcodeFormat, string errorCorrectionLevel, int margin = 1)
{
// 1.设置QR二维码的规格
QrCodeEncodingOptions qrEncodeOption = new QrCodeEncodingOptions();
qrEncodeOption.ErrorCorrection = GetErrorCorrectionLevel(errorCorrectionLevel);
qrEncodeOption.DisableECI = true;
qrEncodeOption.CharacterSet = "UTF-8"; // 设置编码格式,否则读取'中文'乱码
qrEncodeOption.Height = height;
qrEncodeOption.Width = width;
qrEncodeOption.Margin = margin; // 设置周围空白边距
qrEncodeOption.PureBarcode = true;
//System.Windows.Forms.MessageBox.Show("" + qrEncodeOption.ErrorCorrection.Name + "...." + qrEncodeOption.ErrorCorrection.Bits);
// 2.生成条形码图片
BarcodeWriter wr = new BarcodeWriter();
wr.Format = barcodeFormat; // 二维码 BarcodeFormat.QR_CODE
wr.Options = qrEncodeOption;
Bitmap img = wr.Write(codeContent);
return img;
}
/// <summary>
/// 解码二维码,返回一个文本字符串,如果返回为null,则解析(转化)失败
/// </summary>
/// <param name="barcodeBitmap">待解码的二维码图片</param>
/// <returns>扫码结果</returns>
public static string DecodeQrCode(Bitmap barcodeBitmap)
{
BarcodeReader reader = new BarcodeReader();
reader.Options.CharacterSet = "UTF-8";
Result result = reader.Decode(barcodeBitmap);
return (result == null) ? null : result.Text;
}
/// <summary>
/// 获取纠错级别
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private static ErrorCorrectionLevel GetErrorCorrectionLevel(string levelName)
{
switch (levelName)
{
case "L"://bits=1
return ErrorCorrectionLevel.L;
case "M"://bits=0
return ErrorCorrectionLevel.M;
case "Q"://bits=3
return ErrorCorrectionLevel.Q;
case "H"://bits=2
return ErrorCorrectionLevel.H;
default:
return ErrorCorrectionLevel.M;
}
}
}
}
窗体FormQuickResponseCode 主要程序如下(忽略设计器自动生成的代码):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace QRCodeDemo
{
public partial class FormQuickResponseCode : Form
{
public FormQuickResponseCode()
{
InitializeComponent();
//矩阵二维码QRCode: Quick Response Code
rtxtCodeMessage.Text = "https://blog.csdn.net/ylq1045\n斯内科";
this.cboImageFormat.Items.AddRange(new object[] {
"GIF",
"JPG/JPEG",
"PNG",
"BMP"});
this.cboErrorCorrectionLevel.Items.AddRange(new object[] {
"L 7%",
"M 15%",
"Q 25%",
"H 30%"});
cboImageFormat.SelectedIndex = 1;
cboErrorCorrectionLevel.SelectedIndex = 1;
}
private void btnGenerateQR_Click(object sender, EventArgs e)
{
if (rtxtCodeMessage.Text.Length == 0)
{
MessageBox.Show("请输入URL或者文本字符串", "提示");
return;
}
string errorCorrectionLevel = "M";
if (cboErrorCorrectionLevel.Text.Length > 0)
{
errorCorrectionLevel = cboErrorCorrectionLevel.Text.Substring(0, 1);
}
Bitmap bitmap = QrCodeUtil.GeneateQrCode(rtxtCodeMessage.Text, 200, 200, ZXing.BarcodeFormat.QR_CODE,errorCorrectionLevel);
pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
pictureBox1.Image = bitmap;
}
private void btnExport_Click(object sender, EventArgs e)
{
SaveFileDialog saveImageDialog = new SaveFileDialog();
saveImageDialog.Title = "图片保存";
switch (cboImageFormat.Text)
{
case "GIF":
saveImageDialog.Filter = "gif|*.gif|All|*.*";
break;
case "JPG/JPEG":
saveImageDialog.Filter = "jpeg|*.jpg|All|*.*";
break;
case "PNG":
saveImageDialog.Filter = "png|*.png|All|*.*";
break;
case "BMP":
saveImageDialog.Filter = "bmp|*.bmp|All|*.*";
break;
default:
saveImageDialog.Filter = "jpeg|*.jpg|bmp|*.bmp|gif|*.gif|png|*.png|All|*.*";
break;
}
if (saveImageDialog.ShowDialog() == DialogResult.OK)
{
System.Drawing.Imaging.ImageFormat imgformat = GetImageFormat(cboImageFormat.Text);
string fileName = saveImageDialog.FileName;
try
{
pictureBox1.Image.Save(fileName, imgformat);
MessageBox.Show($"导出成功,图片文件路径:\n{fileName}", "导出文件");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "导出文件出错");
}
}
}
private void btnOpenFile_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter= "jpeg|*.jpg|bmp|*.bmp|gif|*.gif|png|*.png|All|*.*";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string fileName = openFileDialog.FileName;
try
{
pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
pictureBox1.Image = Image.FromFile(fileName);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "打开图像文件出错");
}
}
}
private void btnDiscern_Click(object sender, EventArgs e)
{
rtxtCodeMessage.Clear();
try
{
string codeMessage = QrCodeUtil.DecodeQrCode(new Bitmap(pictureBox1.Image));
if (string.IsNullOrEmpty(codeMessage))
{
MessageBox.Show($"识别二维码图片出错,可能不是二维码图片格式,或者过于模糊,\n请打开新的二维码图片重新尝试", "识别二维码图片出错");
return;
}
rtxtCodeMessage.Text = codeMessage;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "识别二维码图片出错");
}
}
/// <summary>
/// 获取图像文件格式
/// </summary>
/// <param name="formatName"></param>
/// <returns></returns>
private System.Drawing.Imaging.ImageFormat GetImageFormat(string formatName)
{
switch (formatName)
{
case "GIF":
return System.Drawing.Imaging.ImageFormat.Gif;
case "JPG/JPEG":
return System.Drawing.Imaging.ImageFormat.Jpeg;
case "PNG":
return System.Drawing.Imaging.ImageFormat.Png;
case "BMP":
return System.Drawing.Imaging.ImageFormat.Bmp;
default:
return System.Drawing.Imaging.ImageFormat.Jpeg;
}
}
}
}