一、什么是条形码
条形码(barcode)是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符.条形码可以标出物品的生产国、制造厂商、商品名称、生产日期、日期等信息,因此得到了广泛应用.
条形码的编码规则
唯一性:同种规格同种产品对应同一个产品代码,同种产品不同规格应对应不同的产品代码.
永久性:产品代码已经分配,就不在更改,并且是终身的.
无含义:为了保证代码有足够的容量以适应产品频繁的更新换代的需要,最好采用无含义的顺序码。
一维条形码
一维条形码只是在一个方向(一般是水平方向)表达信息,而在垂直方向则不表达任何信息,其一定的高度通常是为了便于 阅读器的对准。
一维条形码的应用可以提高信息录入的速度,减少差错率,但是一维条形码也存在一些不足之处:
* 数据容量较小:30个字符左右
* 只能包含字母和数字
* 条形码尺寸相对较大(空间利用率较低)
* 条形码遭到损坏后便不能阅读
二维条形码
在水平和垂直方向的二维空间存储信息的条形码, 称为二维条形码(2-dimensional bar code)。
与一维条形码一样,二维条形码也有许多不同的编码方法,或称码制。就这些码制的编码原理而言,通常可分为以下三种类型:
线性堆叠式二维码、矩阵式二维码、邮政码
数字的含义
此条形码分为4个部分,从左到右分别为:
1-3位:共3位,对应该条码的693,是中国的国家代码之一。(690--695都是中国大陆的代码,由国际上分配)
4-8位:共5位,对应该条码的69838,代表着生产厂商代码,由厂商申请,国家分配
9-12位:共4位,对应该条码的0001,代表着厂内商品代码,由厂商自行确定
第13位:共1位,对应该条码的3,是校验码,依据一定的算法,由前面12位数字计算而得到。
二、通过ZXing.Net来实现条形码
在项目中,点击项目名称右键-->管理NuGet程序包,打开NuGet包管理器窗口,进行搜索下载即可,如下图所示:

如下所示,包含一维条码,二维条码,和带logo的条码实现代码:
1 1 using System; 2 2 using System.Collections.Generic; 3 3 using System.Linq; 4 4 using System.Text; 5 5 using System.Threading.Tasks; 6 6 using System.Drawing; 7 7 using ZXing; 8 8 using ZXing.Common; 9 9 using ZXing.QrCode; 10 10 using ZXing.QrCode.Internal; 11 11 using System.Drawing.Imaging; 12 12 13 13 namespace WindowsFormsApp1 14 14 { 15 15 public class BarMethHepler 16 16 { 17 17 /// <summary> 18 18 /// 生成二维码 19 19 /// </summary> 20 20 /// <param name="text">内容</param> 21 21 /// <param name="width">宽度</param> 22 22 /// <param name="height">高度</param> 23 23 /// <returns></returns> 24 24 public static Bitmap Generate1(string text, int width, int height) 25 25 { 26 26 BarcodeWriter writer = new BarcodeWriter(); 27 27 writer.Format = BarcodeFormat.QR_CODE; 28 28 QrCodeEncodingOptions options = new QrCodeEncodingOptions() 29 29 { 30 30 DisableECI = true,//设置内容编码 31 31 CharacterSet = "UTF-8", //设置二维码的宽度和高度 32 32 Width = width, 33 33 Height = height, 34 34 Margin = 1//设置二维码的边距,单位不是固定像素 35 35 }; 36 36 37 37 writer.Options = options; 38 38 Bitmap map = writer.Write(text); 39 39 return map; 40 40 } 41 41 42 42 /// <summary> 43 43 /// 生成一维条形码 44 44 /// </summary> 45 45 /// <param name="text">内容</param> 46 46 /// <param name="width">宽度</param> 47 47 /// <param name="height">高度</param> 48 48 /// <returns></returns> 49 49 public static Bitmap Generate2(string text, int width, int height) 50 50 { 51 51 BarcodeWriter writer = new BarcodeWriter(); 52 52 //使用ITF 格式,不能被现在常用的支付宝、微信扫出来 53 53 //如果想生成可识别的可以使用 CODE_128 格式 54 54 //writer.Format = BarcodeFormat.ITF; 55 55 writer.Format = BarcodeFormat.CODE_39; 56 56 EncodingOptions options = new EncodingOptions() 57 57 { 58 58 Width = width, 59 59 Height = height, 60 60 Margin = 2 61 61 }; 62 62 writer.Options = options; 63 63 Bitmap map = writer.Write(text); 64 64 return map; 65 65 } 66 66 67 67 /// <summary> 68 68 /// 生成带Logo的二维码 69 69 /// </summary> 70 70 /// <param name="text">内容</param> 71 71 /// <param name="width">宽度</param> 72 72 /// <param name="height">高度</param> 73 73 public static Bitmap Generate3(string text, int width, int height) 74 74 { 75 75 //Logo 图片 76 76 string logoPath = System.AppDomain.CurrentDomain.BaseDirectory + @"\img\logo.png"; 77 77 Bitmap logo = new Bitmap(logoPath); 78 78 //构造二维码写码器 79 79 MultiFormatWriter writer = new MultiFormatWriter(); 80 80 Dictionary<EncodeHintType, object> hint = new Dictionary<EncodeHintType, object>(); 81 81 hint.Add(EncodeHintType.CHARACTER_SET, "UTF-8"); 82 82 hint.Add(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); 83 83 //hint.Add(EncodeHintType.MARGIN, 2);//旧版本不起作用,需要手动去除白边 84 84 85 85 //生成二维码 86 86 BitMatrix bm = writer.encode(text, BarcodeFormat.QR_CODE, width + 30, height + 30, hint); 87 87 bm = deleteWhite(bm); 88 88 BarcodeWriter barcodeWriter = new BarcodeWriter(); 89 89 Bitmap map = barcodeWriter.Write(bm); 90 90 91 91 //获取二维码实际尺寸(去掉二维码两边空白后的实际尺寸) 92 92 int[] rectangle = bm.getEnclosingRectangle(); 93 93 94 94 //计算插入图片的大小和位置 95 95 int middleW = Math.Min((int)(rectangle[2] / 3), logo.Width); 96 96 int middleH = Math.Min((int)(rectangle[3] / 3), logo.Height); 97 97 int middleL = (map.Width - middleW) / 2; 98 98 int middleT = (map.Height - middleH) / 2; 99 99 100100 Bitmap bmpimg = new Bitmap(map.Width, map.Height, PixelFormat.Format32bppArgb); 101101 using (Graphics g = Graphics.FromImage(bmpimg)) 102102 { 103103 g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 104104 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 105105 g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 106106 g.DrawImage(map, 0, 0, width, height); 107107 //白底将二维码插入图片 108108 g.FillRectangle(Brushes.White, middleL, middleT, middleW, middleH); 109109 g.DrawImage(logo, middleL, middleT, middleW, middleH); 110110 } 111111 return bmpimg; 112112 } 113113 114114 /// <summary> 115115 /// 删除默认对应的空白 116116 /// </summary> 117117 /// <param name="matrix"></param> 118118 /// <returns></returns> 119119 private static BitMatrix deleteWhite(BitMatrix matrix) 120120 { 121121 int[] rec = matrix.getEnclosingRectangle(); 122122 int resWidth = rec[2] + 1; 123123 int resHeight = rec[3] + 1; 124124 125125 BitMatrix resMatrix = new BitMatrix(resWidth, resHeight); 126126 resMatrix.clear(); 127127 for (int i = 0; i < resWidth; i++) 128128 { 129129 for (int j = 0; j < resHeight; j++) 130130 { 131131 if (matrix[i + rec[0], j + rec[1]]) 132132 resMatrix[i, j] = true; 133133 } 134134 } 135135 return resMatrix; 136136 } 137137 } 138138 }
简单的练习

设计一个简单的条形码生成程序,主要的三个参数为内容、高度、宽度,再通过在后台调用BarMethHepler类中的Generate1()方法并传入参数就可获得条形码;
实现效果:

参考文献: