WPF如何动态生成Code 39条形码2015-01-01最近在看些条形码方面相关的资料,而如果只是看的话,效果似乎并不怎么好,所以决定动手做点Demo,以增强对相关知识的记忆。这里是一个我编写的使用WPF生成Code 39的例子,Code 39的编码很简单,故而第一次先用它做为尝试。标准的Code 39只支持43个字符,0~9,A~Z,-,.,$, /, +, %以及空格。除此之外,*用于起始和终止符号。而通过使用两个编码符的扩展,则可以支持所有的Acsii码字符。相关知识可以在维基百科上找到。由于是WPF,Demo分为两个文件,xaml文件包含界面布局相关的代码:
<Window x:Class="Code39Demo.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded"><Grid><Grid.RowDefinitions><RowDefinition></RowDefinition><RowDefinition></RowDefinition></Grid.RowDefinitions><TextBox Name="Textbox1" VerticalContentAlignment="Center" TextChanged="Textbox1_TextChanged"></TextBox><Canvas Name="Canvas1" Grid.Row="1"></Canvas></Grid></Window>
using System.Collections.Generic;using System.Text;using System.Text.RegularExpressions;using System.Windows;using System.Windows.Controls;using System.Windows.Media;using System.Windows.Shapes; namespace Code39Demo{/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();} private void Window_Loaded(object sender, RoutedEventArgs e){Textbox1.Focus();} private void Textbox1_TextChanged(object sender, TextChangedEventArgs e){Canvas1.Children.Clear(); TextBox textBox = e.Source as TextBox;if (textBox != null){string content = textBox.Text;if (string.IsNullOrEmpty(content)){textBox.BorderBrush = null;return;} string code = string.Empty;bool result = TryConvertCode(content, out code);if (!result){textBox.BorderBrush = new SolidColorBrush(Colors.Red);textBox.BorderThickness = new Thickness(2);return;}else{textBox.BorderBrush = null;} int thinWidth = 3;int thickWidth = 3 * thinWidth;int currentPos = 10; for (int i = 0; i < code.Length; i++){Rectangle r = new Rectangle();r.Height = 150; Canvas.SetLeft(r, currentPos); switch (code[i]){case "N":{r.Fill = new SolidColorBrush(Colors.Black);currentPos += thinWidth;r.Width = thinWidth;break;}case "n":{r.Fill = new SolidColorBrush(Colors.White);currentPos += thinWidth;r.Width = thinWidth;break;}case "W":{r.Fill = new SolidColorBrush(Colors.Black);currentPos += thickWidth;r.Width = thickWidth;break;}case "w":{r.Fill = new SolidColorBrush(Colors.White);currentPos += thickWidth;r.Width = thickWidth;break;}} Canvas1.Children.Add(r);}}} private bool TryConvertCode(string content, out string code){code = string.Empty;string c = "*" + content + "*";StringBuilder sb = new StringBuilder(); for (int i = 0; i < c.Length; i++){string value = string.Empty;bool result = _code39Map.TryGetValue(c[i], out value);if (!result){return false;} sb.Append(value);sb.Append("n");} code = sb.Remove(sb.Length - 1, 1).ToString(); return true;} private static Dictionary<char, string> _code39Map = new Dictionary<char, string>(); static MainWindow(){_code39Map["0"] = "NnNwWnWnN";_code39Map["1"] = "WnNwNnNnW";_code39Map["2"] = "NnWwNnNnW";_code39Map["3"] = "WnWwNnNnN";_code39Map["4"] = "NnNwWnNnW";_code39Map["5"] = "WnNwWnNnN";_code39Map["6"] = "NnWwWnNnN";_code39Map["7"] = "NnNwNnWnW";_code39Map["8"] = "WnNwNnWnN";_code39Map["9"] = "NnWwNnWnN";_code39Map["A"] = "WnNnNwNnW";_code39Map["B"] = "NnWnNwNnW";_code39Map["C"] = "WnWnNwNnN";_code39Map["D"] = "NnNnWwNnW";_code39Map["E"] = "WnNnWwNnN";_code39Map["F"] = "NnWnWwNnN";_code39Map["G"] = "NnNnNwWnW";_code39Map["H"] = "WnNnNwWnN";_code39Map["I"] = "NnWnNwWnN";_code39Map["J"] = "NnNnWwWnN";_code39Map["K"] = "WnNnNnNwW";_code39Map["L"] = "NnWnNnNwW";_code39Map["M"] = "WnWnNnNwN";_code39Map["N"] = "NnNnWnNwW";_code39Map["O"] = "WnNnWnNwN";_code39Map["P"] = "NnWnWnNwN";_code39Map["Q"] = "NnNnNnWwW";_code39Map["R"] = "WnNnNnWwN";_code39Map["S"] = "NnWnNnWwN";_code39Map["T"] = "NnNnWnWwN";_code39Map["U"] = "WwNnNnNnW";_code39Map["V"] = "NwWnNnNnW";_code39Map["W"] = "WwWnNnNnN";_code39Map["X"] = "NwNnWnNnW";_code39Map["Y"] = "WwNnWnNnN";_code39Map["Z"] = "NwWnWnNnN";_code39Map["-"] = "NwNnNnWnW";_code39Map["."] = "NwNnNnWnW";_code39Map[" "] = "NwWnNnWnN";_code39Map["$"] = "NwNwNwNnN";_code39Map["/"] = "NwNwNnNwN";_code39Map["+"] = "NwNnNwNwN";_code39Map["%"] = "NnNwNwNwN";_code39Map["*"] = "NwNnWnWnN";}}}
各字符对应编码中,W表示黑色宽条,w表示白色宽条,N表示黑色窄条,n表示白色窄条。需要注意的是,Code 39的相邻字符间需要有一个白色窄条用于分隔。这个Demo还欠缺Code 39中校验码的处理(通常不需要),如果有需要的话,可以在此基础上补充,相信并不是困难的工作。