Вопрос

Я хочу создать штрих-коды в кодировке Code39 из моего приложения.

Я знаю, что могу использовать шрифт для этого, но я бы предпочел не делать этого, так как мне пришлось бы регистрировать шрифт на сервере, а у меня был довольно неудачный опыт с этим.

Пример того, что я создал после того, как задал этот вопрос, приведен в ответах

Это было полезно?

Решение

Это мой текущий кодовый файл с большим количеством комментариев:

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("{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

Другие советы

Если вы выберете Code39, вы, вероятно, могли бы использовать этот код, который я написал

http://www.atalasoft.com/cs/blogs/loufranco/archive/2008/03/24/code-39-barcode-generation.aspx

Я написал его, чтобы использовать наш инструментарий для генерации изображений, но вы могли бы переписать его для использования.СЕТЕВОЕ изображение / графика довольно легко.

Я не знаю насчет библиотек - вся работа со штрих-кодом, которую я проделал, была связана со шрифтами штрих-кода.Проверьте бесплатно 3 из 9 если вы используете формат "3 из 9".

Предостережения в отношении 3-из-9:

убедитесь, что весь текст написан заглавными буквами начинайте и заканчивайте каждый штрих-код звездочкой

Вот библиотека рендеринга штрих-кодов с открытым исходным кодом для языков .NET: http://www.codeplex.com/BarcodeRender

Он может отображать некоторые обычные кодировки.

Лицензия выглядит безвредной, и, похоже, ее можно использовать как в приложениях с открытым исходным кодом, так и в коммерческих приложениях (однако, IANAL, возможно, вы захотите проверить ее лицензия себя.)

Вот еще один, также с открытым исходным кодом, использующий лицензию Apache 2.0: http://sourceforge.net/projects/onecode/

Как правило, когда вы с самого начала знаете, что ищете компоненты с открытым исходным кодом, лучше обойти Google и сразу начать поиск на Кузница- источник (в нем есть замечательная система фильтрации результатов поиска, вы можете фильтровать по языку, который, вероятно, вас заинтересует) или на сайте Microsoft CodePlex ( Кодовый комплекс ) (где выбор обычно более ограничен, но что поделаешь.)

вы печатаете на стандартном принтере или на реальном принтере штрих-кодов (zebra или datamax)?и у zebra, и у datamax есть свои собственные языки сценариев - на самом деле они больше похожи на языки разметки.ZPL и DPL соответственно.Мне больше нравятся zebra, и их документация намного чище.

Если у вас нет обычного принтера штрих-кодов, я предлагаю приобрести его и выполнить следующие действия....(это будет намного чище, чем пытаться создавать маленькие блоки изображений и раскрашивать их, имитируя шрифт штрих-кода)

и то, и другое обеспечивает вам большую гибкость, и вы можете предоставить принтеру возможность создавать фактическое изображение штрих-кода.

попросите вашу программу отправить настроенный сценарий ZPL / DPL, включающий значения, которые вы хотите напечатать в виде штрих-кодов, на принтер по ftp.по сути, вы просто "помещаете" текстовый файл, содержащий скрипт, на IP-адрес принтера, и принтер сам заботится о шрифте.

Тот Самый iTextSharp библиотека, предназначенная якобы для создания PDF-файлов, также имеет библиотеку генерации штрих-кодов, которая включает Code39.

Как только вы добавите ссылку на библиотеку DLL, это будет так же просто, как:

Barcode39 code39 = new Barcode39();
code39.Code = "Whatever You're Encoding";

Упс, это C #, но идею вы уловили.После создания вы можете визуализировать изображение практически в любом формате и использовать его по своему усмотрению.

Если вы выполняете рендеринг на стороне клиента, то шрифт может находиться на рабочей станции.Таким образом, вы можете использовать 3 из 9.Я использовал 3 из 9 в нескольких проектах, и это самое простое решение для вас.

Вот пример того, как как сгенерировать штрих-коды Code39 в 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

Вместо использования шрифта штрих-кода я бы предпочел компонент генератора штрих-кодов .net.Ниже приведен vb.net образец для создания кода 39 штрих-кода.

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

На моей последней работе я работал с парой разных библиотек в vb.net для этого.У нас был один, но мы переехали в другой.Я не могу вспомнить их имена (я бы узнал их снова, если бы увидел), но я точно знаю, что и то , и другое были платными, но во время перехода мы оценивали несколько различных компонентов, и я думаю, что один из них был бесплатным.Мы были очень небольшой магазин и очень чувствителен к затратам, поэтому, если бы бесплатный компонент был хоть сколько-нибудь хорош, вы можете поспорить, что мы бы его использовали (я думаю, нам нужна была поддержка 128b, а он обрабатывал только code39).

Я также помню, что причина, по которой мы переключились, заключалась в том, что это было одновременно с переходом с .Net 1.1 на .Net 2.0, и первый компонент выполнял переход слишком медленно.

Итак, вкратце, там что-то есть, но 3 года назад это не было чем-то хорошим.Надеюсь, кто-нибудь еще сможет прийти и указать несколько реальных имен.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top