如何在 vb.net 中生成 Code39 条码
Posted
技术标签:
【中文标题】如何在 vb.net 中生成 Code39 条码【英文标题】:How to generate Code39 barcodes in vb.net 【发布时间】:2010-09-14 01:04:01 【问题描述】:我想从我的应用程序中创建 Code39 编码的条形码。
我知道我可以为此使用字体,但我不想这样做,因为我必须在服务器上注册字体,而且我在这方面有过一些非常糟糕的经历。
我提出这个问题后的一个例子在答案中
【问题讨论】:
【参考方案1】:这是我当前的代码隐藏,有很多 cmets:
Option Explicit On
Option Strict On
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Drawing.Bitmap
Imports System.Drawing.Graphics
Imports System.IO
Partial Public Class Barcode
Inherits System.Web.UI.Page
'Sebastiaan Janssen - 20081001 - TINT-30584
'Most of the code is based on this example:
'http://www.atalasoft.com/cs/blogs/loufranco/archive/2008/04/25/writing-code-39-barcodes-with-javascript.aspx-generation.aspx
'With a bit of this thrown in:
'http://www.atalasoft.com/cs/blogs/loufranco/archive/2008/03/24/code-39-barcode
Private _encoding As Hashtable = New Hashtable
Private Const _wideBarWidth As Short = 8
Private Const _narrowBarWidth As Short = 2
Private Const _barHeight As Short = 100
Sub BarcodeCode39()
_encoding.Add("*", "bWbwBwBwb")
_encoding.Add("-", "bWbwbwBwB")
_encoding.Add("$", "bWbWbWbwb")
_encoding.Add("%", "bwbWbWbWb")
_encoding.Add(" ", "bWBwbwBwb")
_encoding.Add(".", "BWbwbwBwb")
_encoding.Add("/", "bWbWbwbWb")
_encoding.Add("+", "bWbwbWbWb")
_encoding.Add("0", "bwbWBwBwb")
_encoding.Add("1", "BwbWbwbwB")
_encoding.Add("2", "bwBWbwbwB")
_encoding.Add("3", "BwBWbwbwb")
_encoding.Add("4", "bwbWBwbwB")
_encoding.Add("5", "BwbWBwbwb")
_encoding.Add("6", "bwBWBwbwb")
_encoding.Add("7", "bwbWbwBwB")
_encoding.Add("8", "BwbWbwBwb")
_encoding.Add("9", "bwBWbwBwb")
_encoding.Add("A", "BwbwbWbwB")
_encoding.Add("B", "bwBwbWbwB")
_encoding.Add("C", "BwBwbWbwb")
_encoding.Add("D", "bwbwBWbwB")
_encoding.Add("E", "BwbwBWbwb")
_encoding.Add("F", "bwBwBWbwb")
_encoding.Add("G", "bwbwbWBwB")
_encoding.Add("H", "BwbwbWBwb")
_encoding.Add("I", "bwBwbWBwb")
_encoding.Add("J", "bwbwBWBwb")
_encoding.Add("K", "BwbwbwbWB")
_encoding.Add("L", "bwBwbwbWB")
_encoding.Add("M", "BwBwbwbWb")
_encoding.Add("N", "bwbwBwbWB")
_encoding.Add("O", "BwbwBwbWb")
_encoding.Add("P", "bwBwBwbWb")
_encoding.Add("Q", "bwbwbwBWB")
_encoding.Add("R", "BwbwbwBWb")
_encoding.Add("S", "bwBwbwBWb")
_encoding.Add("T", "bwbwBwBWb")
_encoding.Add("U", "BWbwbwbwB")
_encoding.Add("V", "bWBwbwbwB")
_encoding.Add("W", "BWBwbwbwb")
_encoding.Add("X", "bWbwBwbwB")
_encoding.Add("Y", "BWbwBwbwb")
_encoding.Add("Z", "bWBwBwbwb")
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
BarcodeCode39()
Dim barcode As String = String.Empty
If Not IsNothing(Request("barcode")) AndAlso Not (Request("barcode").Length = 0) Then
barcode = Request("barcode")
Response.ContentType = "image/png"
Response.AddHeader("Content-Disposition", String.Format("attachment; filename=barcode_0.png", barcode))
'TODO: Depending on the length of the string, determine how wide the image will be
GenerateBarcodeImage(250, 140, barcode).WriteTo(Response.OutputStream)
End If
End Sub
Protected Function getBCSymbolColor(ByVal symbol As String) As System.Drawing.Brush
getBCSymbolColor = Brushes.Black
If symbol = "W" Or symbol = "w" Then
getBCSymbolColor = Brushes.White
End If
End Function
Protected Function getBCSymbolWidth(ByVal symbol As String) As Short
getBCSymbolWidth = _narrowBarWidth
If symbol = "B" Or symbol = "W" Then
getBCSymbolWidth = _wideBarWidth
End If
End Function
Protected Overridable Function GenerateBarcodeImage(ByVal imageWidth As Short, ByVal imageHeight As Short, ByVal Code As String) As MemoryStream
'create a new bitmap
Dim b As New Bitmap(imageWidth, imageHeight, Imaging.PixelFormat.Format32bppArgb)
'create a canvas to paint on
Dim canvas As New Rectangle(0, 0, imageWidth, imageHeight)
'draw a white background
Dim g As Graphics = Graphics.FromImage(b)
g.FillRectangle(Brushes.White, 0, 0, imageWidth, imageHeight)
'write the unaltered code at the bottom
'TODO: truely center this text
Dim textBrush As New SolidBrush(Color.Black)
g.DrawString(Code, New Font("Courier New", 12), textBrush, 100, 110)
'Code has to be surrounded by asterisks to make it a valid Code39 barcode
Dim UseCode As String = String.Format("010", "*", Code)
'Start drawing at 10, 10
Dim XPosition As Short = 10
Dim YPosition As Short = 10
Dim invalidCharacter As Boolean = False
Dim CurrentSymbol As String = String.Empty
For j As Short = 0 To CShort(UseCode.Length - 1)
CurrentSymbol = UseCode.Substring(j, 1)
'check if symbol can be used
If Not IsNothing(_encoding(CurrentSymbol)) Then
Dim EncodedSymbol As String = _encoding(CurrentSymbol).ToString
For i As Short = 0 To CShort(EncodedSymbol.Length - 1)
Dim CurrentCode As String = EncodedSymbol.Substring(i, 1)
g.FillRectangle(getBCSymbolColor(CurrentCode), XPosition, YPosition, getBCSymbolWidth(CurrentCode), _barHeight)
XPosition = XPosition + getBCSymbolWidth(CurrentCode)
Next
'After each written full symbol we need a whitespace (narrow width)
g.FillRectangle(getBCSymbolColor("w"), XPosition, YPosition, getBCSymbolWidth("w"), _barHeight)
XPosition = XPosition + getBCSymbolWidth("w")
Else
invalidCharacter = True
End If
Next
'errorhandling when an invalidcharacter is found
If invalidCharacter Then
g.FillRectangle(Brushes.White, 0, 0, imageWidth, imageHeight)
g.DrawString("Invalid characters found,", New Font("Courier New", 8), textBrush, 0, 0)
g.DrawString("no barcode generated", New Font("Courier New", 8), textBrush, 0, 10)
g.DrawString("Input was: ", New Font("Courier New", 8), textBrush, 0, 30)
g.DrawString(Code, New Font("Courier New", 8), textBrush, 0, 40)
End If
'write the image into a memorystream
Dim ms As New MemoryStream
Dim encodingParams As New EncoderParameters
encodingParams.Param(0) = New EncoderParameter(Encoder.Quality, 100)
Dim encodingInfo As ImageCodecInfo = FindCodecInfo("PNG")
b.Save(ms, encodingInfo, encodingParams)
'dispose of the object we won't need any more
g.Dispose()
b.Dispose()
Return ms
End Function
Protected Overridable Function FindCodecInfo(ByVal codec As String) As ImageCodecInfo
Dim encoders As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders
For Each e As ImageCodecInfo In encoders
If e.FormatDescription.Equals(codec) Then Return e
Next
Return Nothing
End Function
End Class
【讨论】:
【参考方案2】:如果你选择 Code39,你可能可以从我写的这段代码开始编码
http://www.atalasoft.com/cs/blogs/loufranco/archive/2008/03/24/code-39-barcode-generation.aspx
我编写它是为了使用我们的工具包生成图像,但您可以很容易地重写它以使用 .NET Image/Graphics。
【讨论】:
谢谢,我已经联系了扫描人,Code39 没问题。我使用您的 Javascript 示例构建了一个 .Net 版本,因为您的链接使用了我没有的 dll。 atalasoft.com/cs/blogs/loufranco/archive/2008/04/25/… 酷 -- 是的,我使用我们的产品制作图像,但也可以使用 .NET Image/Bitmap 来完成 -- 我猜你正在这样做。【参考方案3】:我不了解图书馆——我所做的所有条形码工作都是使用条形码字体。如果您使用的是“3 of 9”格式,请查看 free 3-of-9。
3-of-9 的注意事项:
确保所有文本都是大写的 用星号开始和结束每个条形码
【讨论】:
附加警告:它没有被压缩,所以条码宽度很快就会变得很长!但是,+1 因为它非常易于使用!【参考方案4】:这是一个用于 .NET 语言的开源条形码渲染库:http://www.codeplex.com/BarcodeRender
它可以渲染一些常用的编码。
该许可证看起来不错,而且似乎可以在开源和商业应用程序中使用(不过,IANAL,您可能想自己查看它的license。)
这是另一个,也是开源的,使用 Apache 2.0 许可证:http://sourceforge.net/projects/onecode/
一般来说,当你从一开始就知道你在寻找开源组件时,最好绕过谷歌,直接在SourceForge上搜索(它有一个很棒的搜索结果过滤系统,你可以按语言过滤,这可能是您感兴趣的)或 Microsoft 的 CodePlex(选择通常比较有限,但您可以去。)
【讨论】:
谢谢,BarcodeRender 似乎是一个带有严重错误的废弃产品。 Onecode 仅支持美国邮政编码条形码。到目前为止,我还没有在 CodePlex 或 SourceForge 上找到任何其他内容。【参考方案5】:您是打印到标准打印机还是实际的条码打印机(zebra 或 datamax)? zebra 和 datamax 都有自己的脚本语言——实际上更像是标记语言。分别是 ZPL 和 DPL。我更喜欢斑马,而且他们的文档更简洁。
如果您没有合法的条码打印机,我建议您购买一台并执行以下操作....(这比尝试构建小图像块并绘制它们以模拟条码字体要干净得多)
两者都为您提供了极大的灵活性,您可以让打印机处理创建实际的条形码图像。
让您的程序通过 ftp 向打印机发送一个自定义的 ZPL/DPL 脚本,其中包含您希望作为条形码打印的值。基本上,您只需将包含脚本的文本文件“放置”到打印机的 IP 中,打印机就会处理字体。
【讨论】:
【参考方案6】:iTextSharp 库虽然表面上用于创建 PDF,但也有一个包含 Code39 的条形码生成库。
添加对 DLL 的引用后,它就像这样简单:
Barcode39 code39 = new Barcode39();
code39.Code = "Whatever You're Encoding";
糟糕,那是 C#,但你明白了。创建后,您可以以几乎任何图像格式渲染图像并根据需要使用它。
【讨论】:
【参考方案7】:如果您渲染客户端,则字体可以驻留在工作站上。这样您就可以使用 3-of-9。我在几个项目中使用了 3-of-9 和最简单的解决方案。
【讨论】:
【参考方案8】:这是how to generate Code39 barcodes in vb.net 的示例。我现在测试了它,它可以工作。
Public Class code39
Private bitsCode As ArrayList
Public Sub New()
bitsCode = New ArrayList
bitsCode.Add(New String(3) "0001101", "0100111", "1110010", "000000")
bitsCode.Add(New String(3) "0011001", "0110011", "1100110", "001011")
bitsCode.Add(New String(3) "0010011", "0011011", "1101100", "001101")
bitsCode.Add(New String(3) "0111101", "0100001", "1000010", "001110")
bitsCode.Add(New String(3) "0100011", "0011101", "1011100", "010011")
bitsCode.Add(New String(3) "0110001", "0111001", "1001110", "011001")
bitsCode.Add(New String(3) "0101111", "0000101", "1010000", "011100")
bitsCode.Add(New String(3) "0111011", "0010001", "1000100", "010101")
bitsCode.Add(New String(3) "0110111", "0001001", "1001000", "010110")
bitsCode.Add(New String(3) "0001011", "0010111", "1110100", "011010")
End Sub
Public Function Generate(ByVal Code As String) As Image
Dim a As Integer = 0
Dim b As Integer = 0
Dim imgCode As Image
Dim g As Graphics
Dim i As Integer
Dim bCode As Byte()
Dim bitCode As Byte()
Dim tmpFont As Font
If Code.Length <> 12 Or Not IsNumeric(Code.Replace(".", "_").Replace(",", "_")) Then Throw New Exception("Le code doit être composé de 12 chiffres")
ReDim bCode(12)
For i = 0 To 11
bCode(i) = CInt(Code.Substring(i, 1))
If (i Mod 2) = 1 Then
b += bCode(i)
Else
a += bCode(i)
End If
Next
i = (a + (b * 3)) Mod 10
If i = 0 Then
bCode(12) = 0
Else
bCode(12) = 10 - i
End If
bitCode = getBits(bCode)
tmpFont = New Font("times new roman", 14, FontStyle.Regular, GraphicsUnit.Pixel)
imgCode = New Bitmap(110, 50)
g = Graphics.FromImage(imgCode)
g.Clear(Color.White)
g.DrawString(Code.Substring(0, 1), tmpFont, Brushes.Black, 2, 30)
a = g.MeasureString(Code.Substring(0, 1), tmpFont).Width
For i = 0 To bitCode.Length - 1
If i = 2 Then
g.DrawString(Code.Substring(1, 6), tmpFont, Brushes.Black, a, 30)
ElseIf i = 48 Then
g.DrawString(Code.Substring(7, 5) & bCode(12).ToString, tmpFont, Brushes.Black, a, 30)
End If
If i = 0 Or i = 2 Or i = 46 Or i = 48 Or i = 92 Or i = 94 Then
If bitCode(i) = 1 Then 'noir
g.DrawLine(Pens.Black, a, 0, a, 40)
a += 1
End If
Else
If bitCode(i) = 1 Then 'noir
g.DrawLine(Pens.Black, a, 0, a, 30)
a += 1
Else 'blanc
a += 1
End If
End If
Next
g.Flush()
Return imgCode
End Function
Private Function getBits(ByVal bCode As Byte()) As Byte()
Dim i As Integer
Dim res As Byte()
Dim bits As String = "101"
Dim cle As String = bitsCode(bCode(0))(3)
For i = 1 To 6
bits &= bitsCode(bCode(i))(CInt(cle.Substring(i - 1, 1)))
Next
bits &= "01010"
For i = 7 To 12
bits &= bitsCode(bCode(i))(2)
Next
bits += "101"
ReDim res(bits.Length - 1)
For i = 0 To bits.Length - 1
res(i) = Asc(bits.Chars(i)) - 48
Next
Return res
End Function
End Class
【讨论】:
这是 EAN 13,它仅适用于 12 位条形码,而不是其规定的代码 39【参考方案9】:我更喜欢.net barcode generator component,而不是使用条形码字体。下面是vb.net sample for creating Code 39 barcode。
Imports System.IO
Imports PQScan.BarcodeCreator
Namespace BarcodeGeneratorVB
Class Program
Private Shared Sub Main(args As String())
Dim barcode As New Barcode()
barcode.Data = "www.pqscan.com"
barcode.BarType = BarCodeType.Code39
barcode.Width = 300
barcode.Height = 100
barcode.CreateBarcode("code39-vb.jpeg")
End Sub
End Class
End Namespace
【讨论】:
【参考方案10】:在我的上一份工作中,我为此在 vb.net 中使用了几个不同的库。我们有一个,然后搬到了另一个。我不记得他们的名字(如果我看到他们我会再次认出他们),但我知道两者都是付费的,我们在切换时评估了几个不同的组件,我认为这包括一个免费的。我们是一家非常小店并且非常成本敏感,所以如果免费组件有任何好处,你可以打赌我们会使用它(我认为我们需要 128b 支持,它只处理代码39)。
我还记得我们切换的原因是我们从 .Net 1.1 迁移到 .Net 2.0 的同时,第一个组件在转换时太慢了。
所以,总而言之,那里有一些东西,但在 3 年前并不是什么好东西。希望其他人可以过来填写一些实际姓名。
【讨论】:
以上是关于如何在 vb.net 中生成 Code39 条码的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法在 TD 6.3 中生成有效的 Code128 条码?
VB.NET如何操作条码扫描枪,如何设置,如何进行条形码的设置及打印