C#轻松实现条形码二维码生成及识别

一、前言

大家好!我是付工。

今天给大家分享一下,如何基于C#来生成并识别条形码或者二维码。

二、ZXing.Net

实现二维码生成的库有很多,我们这里采用的是http://ZXing.Net

ZXing是一个开放源码的,用Java实现的多种格式的一维二维条码图像处理库,而http://ZXing.Net是ZXing在.Net平台下的实现。

我们通过Nuget搜索http://zxing.net即可搜索安装。

三、BarCodeHelper

安装好http://ZXing.Net后,我们创建一个BarCodeHelper,对于进行封装,封装了以下几个方法:

方法一:生成条形码

public static Bitmap GenerateBarCode(string text, int width, int height)
{
    BarcodeWriter writer = new BarcodeWriter();
    writer.Format = BarcodeFormat.CODE_39;
    EncodingOptions options = new EncodingOptions()
    {
        Width = width,
        Height = height,
        Margin = 2,
        PureBarcode = true
    };
    writer.Options = options;
    Bitmap map = writer.Write(text);
    return map;
}

方法二:生成二维码

public static Bitmap GenerateQRCode(string text, int width, int height)
{
    BarcodeWriter writer = new BarcodeWriter();
    writer.Format = BarcodeFormat.QR_CODE;
    QrCodeEncodingOptions options = new QrCodeEncodingOptions()
    {
        DisableECI = true,//设置内容编码
        CharacterSet = "UTF-8",  //设置二维码的宽度和高度
        Width = width,
        Height = height,
        Margin = 1//设置二维码的边距,单位不是固定像素
    };
    writer.Options = options;

    Bitmap map = writer.Write(text);
    return map;
}

方法三:生成带Logo二维码

public static Bitmap GenerateQRCodeWithLogo(string text, int width, int height, Bitmap logo)
{
    //构造二维码写码器
    MultiFormatWriter writer = new MultiFormatWriter();
    Dictionary<EncodeHintType, object> hint = new Dictionary<EncodeHintType, object>();
    hint.Add(EncodeHintType.CHARACTER_SET, "UTF-8");
    hint.Add(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
    //生成二维码 
    BitMatrix bm = writer.encode(text, BarcodeFormat.QR_CODE, width, height, hint);
    BarcodeWriter barcodeWriter = new BarcodeWriter();
    Bitmap map = barcodeWriter.Write(bm);
    //获取二维码实际尺寸
    int[] rectangle = bm.getEnclosingRectangle();
    //计算插入图片的大小和位置
    int middleW = Math.Min((int)(rectangle[2] / 3.5), logo.Width);
    int middleH = Math.Min((int)(rectangle[3] / 3.5), logo.Height);
    int middleL = (map.Width - middleW) / 2;
    int middleT = (map.Height - middleH) / 2;
    Bitmap bmpimg = new Bitmap(map.Width, map.Height, PixelFormat.Format32bppArgb);
    using (Graphics g = Graphics.FromImage(bmpimg))
    {
        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
        g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
        g.DrawImage(map, 0, 0, width, height);
    }
    //将二维码插入图片
    Graphics myGraphic = Graphics.FromImage(bmpimg);
    //白底
    myGraphic.FillRectangle(Brushes.Transparent, middleL, middleT, middleW, middleH);
    myGraphic.DrawImage(logo, middleL, middleT, middleW, middleH);
    return bmpimg;
}

方法四:识别条码二维码

public static string ReadCode(Bitmap bitmap)
{
    BarcodeReader barcodeReader = new BarcodeReader();
    barcodeReader.Options.CharacterSet = "UTF-8";
    Result result = barcodeReader.Decode(bitmap);
    return result.Text;
}

四、案例应用

有了以上方法后,编写一个案例来进行功能测试。

按钮事件代码很简单,就是调用BarCodeHelper中的对应方法即可:

private void btn_BarCode_Click(object sender, EventArgs e)
{
    this.pic_BarCode.Image = BarCodeHelper.GenerateBarCode(this.txt_BarCode.Text, this.pic_BarCode.Width, this.pic_BarCode.Height);
}

private void btn_QRCode_Click(object sender, EventArgs e)
{
    if (chk_Logo.Checked)
    {
        this.pic_QRCode.Image = BarCodeHelper.GenerateQRCodeWithLogo(this.txt_QRCode.Text,
this.pic_QRCode.Width, this.pic_QRCode.Height, new Bitmap(this.pic_Logo.Image));
    }
    else
    {
        this.pic_QRCode.Image = BarCodeHelper.GenerateQRCode(this.txt_QRCode.Text, this.pic_QRCode.Width, this.pic_QRCode.Height);
    }
}

private void btn_ReadQRCode_Click(object sender, EventArgs e)
{
    MessageBox.Show(BarCodeHelper.ReadCode(new Bitmap(this.pic_QRCode.Image)));
}

private void btn_ReadBarCode_Click(object sender, EventArgs e)
{
    MessageBox.Show(BarCodeHelper.ReadCode(new Bitmap(this.pic_BarCode.Image)));
}

最终实现效果如下所示:

/// <summary> /// 生成条码 /// </summary> private void btnEncode_Click(object sender, EventArgs e) { errorProvider1.Clear(); int W = Convert.ToInt32(this.txtWidth.Text.Trim()); int H = Convert.ToInt32(this.txtHeight.Text.Trim()); int AddNum = Convert.ToInt32(this.tbAddNum.Text.Trim()); int SerialNo = Convert.ToInt32(this.tbSerialNO.Text.Trim()); CodeLib.AlignmentPositions Align = CodeLib.AlignmentPositions.CENTER; switch (cbBarcodeAlign.SelectedItem.ToString().Trim().ToLower()) { case "left": Align = CodeLib.AlignmentPositions.LEFT; break; case "right": Align = CodeLib.AlignmentPositions.RIGHT; break; default: Align = CodeLib.AlignmentPositions.CENTER; break; } CodeLib.TYPE type = CodeLib.TYPE.UNSPECIFIED; switch (cbEncodeType.SelectedItem.ToString().Trim()) { case "Code 128": type = CodeLib.TYPE.CODE128; break; case "Code 128-A": type = CodeLib.TYPE.CODE128A; break; case "Code 128-B": type = CodeLib.TYPE.CODE128B; break; default: MessageBox.Show("请指定编码类型。"); break; } try { if (type != CodeLib.TYPE.UNSPECIFIED) { b.IncludeLabel = this.chkGenerateLabel.Checked; b.Alignment = Align; switch (this.cbLabelLocation.SelectedItem.ToString().Trim().ToUpper()) { case "BOTTOMLEFT": b.LabelPosition = CodeLib.LabelPositions.BOTTOMLEFT; break; case "BOTTOMRIGHT": b.LabelPosition = CodeLib.LabelPositions.BOTTOMRIGHT; break; case "TOPCENTER": b.LabelPosition = CodeLib.LabelPositions.TOPCENTER; break; case "TOPLEFT": b.LabelPosition = CodeLib.LabelPositions.TOPLEFT; break; case "TOPRIGHT": b.LabelPosition = CodeLib.LabelPositions.TOPRIGHT; break; default: b.LabelPosition = CodeLib.LabelPositions.BOTTOMCENTER; break; } int SerialLen = this.tbSerialNO.Text.Trim().Length; string Barcodedata = ""; int i = 0; do { int zeroNum = SerialLen - SerialNo.ToString().Trim().Length; switch (zeroNum) { case 0: Barcodedata = this.txtData.Text.Trim() + SerialNo.ToString(); break; case 1: Barcodedata = this.txtData.Text.Trim() + SerialNo.ToString().Insert(0, "0"); break; case 2: Barcodedata = this.txtData.Text.Trim() + SerialNo.ToString().Insert(0, "00"); break; case 3: Barcodedata = this.txtData.Text.Trim() + SerialNo.ToString().Insert(0, "000"); break; default : Barcodedata = this.txtData.Text.Trim() + SerialNo.ToString().Insert(0, "0000"); break; } barcode.Image = b.Encode(type, Barcodedata.ToString(), W, H); i++; SerialNo++; this.Refresh(); Thread.Sleep(1000); //Printer(); //打印 //Thread.Sleep(500); } while (i< AddNum); } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
### C#生成和读取二维码的方法 #### 使用 ZXing.Net 库处理二维码 为了在 C# 程序中实现二维码生成与读取,推荐使用开源库 ZXing.Net (Zebra Crossing),该库支持多种类型的条形码以及 QR Code 的编码解码操作。 安装方式可以通过 NuGet Package Manager 安装 `ZXing.Net` 和 `ZXing.Common.ReedSolomon` 这两个包来获取必要的依赖项[^2]。 #### 生成二维码实例 下面展示如何利用上述提到的 ZXing.Net 类库创建一个简单的控制台应用程序,在其中定义函数以生成指定文本内容对应的 QR Code 图像文件: ```csharp using System; using ZXing; using ZXing.QrCode; public class QrCodeGenerator { public static void GenerateQrCode(string content, string outputPath) { var writer = new BarcodeWriter(); writer.Format = BarcodeFormat.QR_CODE; // 设置编码参数 var options = new EncodingOptions() { Width = 300, Height = 300 }; ((BarcodeWriterGeneric)writer).Renderer = new BitmapRenderer(options); // 将字符串写入到图片对象并保存至磁盘路径 using(var bitmap = writer.Write(content)) { bitmap.Save(outputPath); } } } ``` 此代码片段展示了通过设置宽度高度等属性来自定义输出图像尺寸,并最终调用 Write 方法完成实际的数据转换过程。 #### 解析二维码实例 对于已有的 QR Code 图片资源,可以采用如下所示的方式对其进行扫描分析从而提取内含的信息: ```csharp using System.Drawing; using ZXing; public class QrCodeReader { public static string DecodeImage(string imagePath) { var reader = new BarcodeReader(); reader.Options.PossibleFormats = new[] { BarcodeFormat.QR_CODE }; // 加载要解析的目标位图数据 using(var bitmap = new Bitmap(imagePath)) { var result = reader.Decode(bitmap); // 返回识别出来的原始字符序列 return result?.Text ?? ""; } } } ``` 这里先指定了可能遇到的具体格式类型以便提高匹配效率;接着加载目标图形作为输入源交给 BarcodeReader 实例去执行具体的解密工作。最后返回所获得的结果串或者空字符串表示失败情况下的默认值[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上位机付工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值