Code 39 條碼基礎知識
- 字符集:0-9, A-Z, -, ., $, /, +, %, 空格(共 43 個字符)
- 每字符由 9 個元素組成(5 條粗條、4 條細條),起止符為 *
- 無校驗碼,自檢能力弱,不適用高可靠需求場景
- 寬窄比通常 2:1 至 3:1
方案一:使用開源庫 BarcodeLib(推薦新手)
// NuGet: Install-Package BarcodeLib
using BarcodeLib;
public Image GenerateCode39(string data, int width = 300, int height = 150) {
Barcode barcode = new Barcode();
barcode.IncludeLabel = true; // 顯示底部文字
barcode.Alignment = AlignmentPositions.CENTER;
barcode.RotateFlipType = RotateFlipType.RotateNoneFlipNone;
barcode.LabelFont = new Font("Consolas", 10, FontStyle.Bold);
return barcode.Encode(TYPE.CODE39, data, Color.Black, Color.White, width, height);
}
// 在 PictureBox 顯示
pictureBox1.Image = GenerateCode39("HELLO123");
方案二:手寫繪製邏輯(無依賴、教學用)
private static readonly Dictionary Code39Map = new Dictionary {
{'0',"█ █ ███ █"}, {'1',"███ █ █ █"}, /* ... 完整映射表 ... */
{'*',"█ █ ███ █ █"} // 起止符
};
public Bitmap DrawCode39(string input, int narrowWidth = 2, int height = 100) {
string encoded = "*" + input.ToUpper() + "*";
int wideWidth = narrowWidth * 3;
int totalWidth = encoded.Length * (narrowWidth * 5 + wideWidth * 4) - narrowWidth; // 間隙
var bmp = new Bitmap(totalWidth, height);
using (var g = Graphics.FromImage(bmp)) {
g.Clear(Color.White);
int x = 0;
bool isBar = true;
foreach (char c in encoded) {
if (!Code39Map.TryGetValue(c, out string pattern)) continue;
foreach (char p in pattern) {
int w = (p == '█') ? wideWidth : narrowWidth;
if (isBar) g.FillRectangle(Brushes.Black, x, 0, w, height);
x += w;
isBar = !isBar;
}
x += narrowWidth; // 字符間隙
isBar = true;
}
}
return bmp;
}
方案三:ZXing.Net 專業級條碼生成與識別
// NuGet: Install-Package ZXing.Net
using ZXing;
using ZXing.Common;
using ZXing.Rendering;
public Bitmap GenerateCode39ZXing(string content, int width, int height) {
var writer = new BarcodeWriterPixelData {
Format = BarcodeFormat.CODE_39,
Options = new EncodingOptions {
Width = width,
Height = height,
Margin = 10,
PureBarcode = false // 含文字
},
Renderer = new PixelDataRenderer()
};
var pixelData = writer.Write(content);
var bmp = new Bitmap(pixelData.Width, pixelData.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
var bmpData = bmp.LockBits(new Rectangle(0,0,bmp.Width,bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, bmp.PixelFormat);
System.Runtime.InteropServices.Marshal.Copy(pixelData.Pixels, 0, bmpData.Scan0, pixelData.Pixels.Length);
bmp.UnlockBits(bmpData);
return bmp;
}
生產環境部署檢查清單
- ✅ 輸入驗證:過濾非法字符、長度限制(建議 ≤ 80 字符)
- ✅ 打印測試:不同 DPI 打印機掃描驗證(最小模組寬度 ≥ 0.19mm)
- ✅ 異常處理:捕獲編碼異常、GDI+ 異常、內存不足
- ✅ 資源釋放:Bitmap、Graphics、非托管資源及時 Dispose
- ✅ 單元測試:覆蓋邊界字符、空字串、超長輸入