Comment générer des codes à barres Code39 dans vb.net
Question
Je souhaite créer des codes à barres codés Code39 à partir de mon application.
Je sais que je peux utiliser une police pour cela, mais je préférerais ne pas le faire, car je devrais enregistrer la police sur le serveur et j'ai eu de très mauvaises expériences avec cela.
Un exemple de ce que j'ai produit après avoir posé cette question se trouve dans les réponses
La solution
Ceci est mon code actuel derrière, avec beaucoup de commentaires:
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("<*>quot;, "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("{0}{1}{0}", "*", 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
Autres conseils
Si vous choisissez Code39, vous pourriez probablement coder à partir de ce code que j'ai écrit
.http: //www.atalasoft.com/cs/blogs/loufranco/archive/2008/03/24/code-39-barcode-generation.aspx
Je l'ai écrit pour utiliser notre boîte à outils pour la génération d'images, mais vous pouvez le réécrire pour utiliser .NET Image / Graphics assez facilement.
Je ne connais pas les bibliothèques - tout le travail que j'ai effectué sur les codes à barres a été fait avec des polices de codes à barres. Consultez gratuit 3 sur 9 si vous utilisez le " 3 sur 9 ". ; format.
Mises en garde de 3 sur 9:
assurez-vous que tout le texte est en majuscule commence et termine chaque code à barres par un astérisque
Voici une bibliothèque de rendu de code à barres open source pour les langages .NET: http://www.codeplex.com/BarcodeRender
Il peut restituer certains encodages habituels.
La licence semble inoffensive et semble utilisable aussi bien dans les applications open source que dans les applications commerciales (toutefois, IANAL, vous pouvez vérifier sa licence vous-même.)
En voici un autre, également open source, utilisant la licence Apache 2.0: http://sourceforge.net/ projets / code unique /
En règle générale, lorsque vous savez dès le départ que vous recherchez des composants open source, il est préférable de contourner Google et de lancer directement la recherche sur . SourceForge (il possède un excellent système de filtrage pour les résultats de recherche. Vous pouvez filtrer par langue, ce qui vous intéresse probablement) ou sur Microsoft CodePlex (où le choix est généralement plus limité, mais voilà.)
imprimez-vous sur une imprimante standard ou une imprimante à code-barres (zebra ou datamax)? zebra et datamax ont tous les deux leur propre langage de script, qui s'apparente davantage à un langage de balisage. ZPL et DPL respectivement. J'aime plus les zèbres et leur documentation est beaucoup plus propre.
Si vous ne possédez pas d’imprimante de code à barres légitime, je suggère d’en acheter une et de procéder comme suit .... (ce sera beaucoup plus propre que de tenter de construire de petits blocs d’image et de les peindre pour simuler une police de code à barres )
vous permettent une grande flexibilité et vous pouvez laisser l’imprimante gérer la création de l’image réelle du code à barres.
demandez à votre programme d’envoyer un script ZPL / DPL personnalisé contenant les valeurs à imprimer en tant que codes à barres vers l’imprimante via ftp. En gros, vous venez de "mettre" un fichier texte contenant le script sur l’IP de l’imprimante et celle-ci s’occupe de la police.
La bibliothèque iTextSharp , tout en permettant de créer des fichiers PDF, comporte également une bibliothèque de génération de codes à barres incluant Code39. .
Une fois que vous avez ajouté une référence à la DLL, il suffit de:
Barcode39 code39 = new Barcode39();
code39.Code = "Whatever You're Encoding";
Oups, c'est C #, mais vous voyez l'idée. Une fois créée, vous pouvez restituer une image dans n’importe quel format et l’utiliser à votre guise.
Si vous rendez le côté client, la police peut résider sur un poste de travail. De cette façon, vous pouvez utiliser 3 sur 9. J'ai utilisé 3 sur 9 dans plusieurs projets et la solution la plus simple pour vous.
Voici un exemple de comment générer des codes à barres Code39 dans vb.net . Je l'ai testé maintenant et cela fonctionne.
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
Au lieu d'utiliser une police de code-barres, je préférerais un composant .net du générateur de code-barres . Vous trouverez ci-dessous un exemple de vb.net pour la création de code à barres .
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
Lors de mon dernier emploi, je travaillais pour cela avec plusieurs bibliothèques différentes sur vb.net. Nous en avons eu un et avons déménagé dans un autre. Je ne me souviens plus de leurs noms (je les reconnaîtrais encore si je les voyais), mais je sais que les deux étaient payants, nous avons évalué plusieurs composants différents au moment du changement, et je pense que cela incluait un gratuit. Nous étions un très petit magasin et des très coûts sensibles, donc si la composante gratuite était bonne, vous pouvez parier que nous l'aurions utilisée (je pense que nous avions besoin de l'aide de 128b et ne traitait que le code39).
Je me souviens également que la raison pour laquelle nous avons changé est que c’était en même temps que nous passions de .Net 1.1 à .Net 2.0 et que le premier composant était trop lent pour effectuer la transition.
Donc, en résumé, il y a quelque chose qui existe, mais ce n’était pas bon il ya 3 ans. Espérons que quelqu'un d'autre puisse venir et donner quelques noms réels.