سؤال

أرغب في إنشاء رموز شريطية مشفرة 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

لقد كتبته لاستخدام مجموعة الأدوات الخاصة بنا لإنشاء الصور، ولكن يمكنك إعادة كتابته لاستخدام .NET Image/Graphics بسهولة تامة.

لا أعرف شيئًا عن المكتبات - كل أعمال الباركود التي قمت بها كانت باستخدام خطوط الباركود.الدفع مجاني 3 من 9 إذا كنت تستخدم التنسيق "3 من 9".

تحذيرات 3 من 9:

تأكد من أن كل النص في حالة بدء العلبة العليا وإنهاء كل رمز باركي مع النجمة

فيما يلي مكتبة عرض الباركود مفتوحة المصدر للغات .NET: http://www.codeplex.com/BarcodeRender

يمكنه تقديم بعض الترميزات المعتادة.

يبدو الترخيص سليمًا، ويبدو أنه قابل للاستخدام في كل من التطبيقات مفتوحة المصدر والتطبيقات التجارية (ومع ذلك، يا IANAL، قد ترغب في التحقق من صلاحيته رخصة نفسك.)

إليك واحدة أخرى، مفتوحة المصدر أيضًا، تستخدم ترخيص Apache 2.0: http://sourceforge.net/projects/onecode/

بشكل عام، عندما تعلم منذ البداية أنك تبحث عن مكونات مفتوحة المصدر، فمن الأفضل تجاوز Google والبدء مباشرة في البحث عنها. سورس فورج (يحتوي على نظام تصفية رائع لنتائج البحث، يمكنك التصفية حسب اللغة، وهو ما قد يثير اهتمامك) أو على Microsoft كودبلكس (حيث يكون الاختيار عادة أكثر محدودية، ولكن هذا هو الحال.)

هل تقوم بالطباعة على طابعة قياسية أم طابعة باركود فعلية (زيبرا أو داتاماكس)؟يمتلك كل من zebra وdatamax لغات البرمجة النصية الخاصة بهما - وهي في الواقع أشبه باللغات الترميزية.ZPL وDPL على التوالي.أنا أحب الحمار الوحشي أكثر ووثائقهم أكثر نظافة.

إذا لم يكن لديك طابعة باركود شرعية، أقترح عليك شراء واحدة والقيام بما يلي....(سيكون الأمر أكثر نظافة من محاولة إنشاء كتل صور صغيرة ورسمها لمحاكاة خط الرمز الشريطي)

كلاهما يتيح لك مرونة كبيرة ويمكنك السماح للطابعة بالتعامل مع إنشاء صورة الباركود الفعلية.

اطلب من برنامجك إرسال برنامج نصي ZPL/DPL مخصص يتضمن القيم التي تريد طباعتها كرموز شريطية إلى الطابعة عبر بروتوكول نقل الملفات.في الأساس، كل ما عليك فعله هو "وضع" ملف نصي يحتوي على البرنامج النصي في عنوان 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 لإنشاء الرمز الشريطي Code 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، ولم يتعامل إلا مع الكود 39).

وأتذكر أيضًا أن سبب تبديلنا هو أنه في نفس الوقت انتقلنا من .Net 1.1 إلى .Net 2.0، وكان المكون الأول بطيئًا جدًا في إجراء النقل.

باختصار، هناك شيء ما، لكنه لم يكن جيدًا قبل 3 سنوات.نأمل أن يأتي شخص آخر ويملأ بعض الأسماء الفعلية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top