VintaSoft Barcode .NET SDK v10.0
In This Topic
    How to use Structure Append feature for distributing data message across several 2D barcodes?
    In This Topic

    Structure Append feature allows to distribute data message across several 2D barcodes if data message cannot be stored in a single 2D barcode. Up to 16 DataMatrix, 16 QR, 26 Aztec, 99999 PDF417, 9 Code16K symbols may be appended in a structured format.

    Example: Here is an example that shows how to use Structure Append feature for distributing data message across several 2D barcodes.

    Imports System.Drawing
    Imports System.Text
    Imports Vintasoft.Barcode
    Imports Vintasoft.Barcode.BarcodeInfo
    
    ''' <summary>
    ''' Test that shows how to use Structured Append feature for distributing data message across
    ''' several 2D barcodes.
    ''' </summary>
    Class StructureAppendExample
    
            ''' <summary>
            ''' Runs the test.
            ''' </summary>
            Public Shared Sub Test()
                    Dim barcodeType__1 As BarcodeType = BarcodeType.DataMatrix
    
                    Dim symbolsCount As Integer = 5
    
                    Dim symbolsValue As String = "In order to fit a non-square area or to handle larger messages than are practical " & "in a single symbol, a data message can be distributed across several symbols. " & "Aztec, Code 16K, DataMatrix, MaxiCode, QR Code, PDF417, Micro PDF417 " & "symbols may be appended in a structured format."
    
                    ' split data and generate barcodes
                    Dim barcodeImages As Image() = GenerateBarcodes(barcodeType__1, symbolsValue, symbolsCount)
    
                    ' resort barcode images
                    Array.Reverse(barcodeImages)
                    Array.Reverse(barcodeImages, 0, barcodeImages.Length \ 2)
    
                    ' read barcodes and merge data value
                    Dim readValue As String = ReadBarcodeValue(barcodeImages, barcodeType__1)
    
                    If readValue = symbolsValue Then
                            Console.WriteLine("Success")
                    Else
                            Throw New ApplicationException()
                    End If
            End Sub
    
            ''' <summary>
            ''' Splits value and generates symbolCount barcodes using Structured Append.
            ''' </summary>
            Public Shared Function GenerateBarcodes(barcodeType__1 As BarcodeType, value As String, symbolCount As Integer) As Image()
                    ' create an image array
                    Dim result As Image() = New Image(symbolCount - 1) {}
    
                    ' create the barcode writer
                    Dim writer As New BarcodeWriter()
    
                    ' specify that writer must generate barcode of specified type
                    writer.Settings.Barcode = barcodeType__1
    
                    ' create parity data for a QR barcode value
                    Dim parityData As Byte = 0
                    If barcodeType__1 = BarcodeType.QR Then
                            parityData = QRStructuredAppendCharacter.CaluculateParityData(value)
                    End If
    
                    ' generate symbols(barcodes)
                    Dim fragmentLength As Integer = value.Length \ symbolCount
                    For i As Integer = 0 To symbolCount - 1
                            ' create Structured Append character
    
                            Dim structureAppendCharacter As StructuredAppendCharacter
                            Select Case barcodeType__1
                                    Case BarcodeType.Aztec
                                            structureAppendCharacter = New AztecStructuredAppendCharacter(i + 1, symbolCount, "")
                                            Exit Select
    
                                    Case BarcodeType.DataMatrix
                                            structureAppendCharacter = New DataMatrixStructuredAppendCharacter(i + 1, symbolCount, 0)
                                            Exit Select
    
                                    Case BarcodeType.QR
                                            structureAppendCharacter = New QRStructuredAppendCharacter(i + 1, symbolCount, parityData)
                                            Exit Select
    
                                    Case BarcodeType.Code16K
                                            structureAppendCharacter = New StructuredAppendCharacter(i + 1, symbolCount)
                                            writer.Settings.Height = 200
                                            Exit Select
    
                                    Case BarcodeType.MaxiCode
                                            structureAppendCharacter = New StructuredAppendCharacter(i + 1, symbolCount)
                                            Exit Select
    
                                    Case BarcodeType.MicroPDF417
                                            structureAppendCharacter = New PDF417StructuredAppendCharacter(i + 1, symbolCount, "123")
                                            Exit Select
    
                                    Case BarcodeType.PDF417
                                            structureAppendCharacter = New PDF417StructuredAppendCharacter(i + 1, symbolCount, "123")
                                            Exit Select
                                    Case Else
    
                                            Throw New NotSupportedException()
                            End Select
    
                            ' create symbol data
    
                            Dim symbolTextData As String
                            If i = symbolCount - 1 Then
                                    symbolTextData = value.Substring(i * fragmentLength)
                            Else
                                    symbolTextData = value.Substring(i * fragmentLength, fragmentLength)
                            End If
    
                            Dim symbolData As New TextValueItem(symbolTextData)
    
                            ' set the barcode value items
                            writer.Settings.ValueItems = New ValueItemBase() {structureAppendCharacter, symbolData}
    
                            ' create image with barcode
                            result(i) = writer.GetBarcodeAsBitmap()
                    Next
    
                    Return result
            End Function
    
            ''' <summary>
            ''' Reads barcodes and merges the results into a single value.
            ''' </summary>
            Private Shared Function ReadBarcodeValue(barcodeImages As Image(), barcodeType As BarcodeType) As String
                    ' create the barcode reader
                    Using reader As New BarcodeReader()
                            ' specify that reader must search for barcodes of specified type
                            reader.Settings.ScanBarcodeTypes = barcodeType
    
                            ' barcode reading results
                            Dim readingResults As IBarcodeInfo() = New IBarcodeInfo(barcodeImages.Length - 1) {}
                            ' read barcodes
                            For i As Integer = 0 To barcodeImages.Length - 1
                                    ' read barcode from image
                                    readingResults(i) = reader.ReadBarcodes(barcodeImages(i))(0)
    
                                    ' dispose image
                                    barcodeImages(i).Dispose()
                            Next
    
                            ' determine symbol count
                            Dim symbolsCount As Integer = 0
                            For i As Integer = 0 To readingResults.Length - 1
                                    If TypeOf readingResults(i).ValueItems(0) Is StructuredAppendCharacter Then
                                            symbolsCount = DirectCast(readingResults(i).ValueItems(0), StructuredAppendCharacter).SymbolCount
                                            Exit For
                                    End If
                            Next
                            If symbolsCount = 0 Then
                                    Throw New ApplicationException("No Structured Append symbols.")
                            End If
    
                            ' create array of string
                            Dim resultValues As String() = New String(symbolsCount - 1) {}
                            ' fill resultValues
                            For i As Integer = 0 To readingResults.Length - 1
                                    If TypeOf readingResults(i).ValueItems(0) Is StructuredAppendCharacter Then
                                            Dim structureAppendCharacter As StructuredAppendCharacter = DirectCast(readingResults(i).ValueItems(0), StructuredAppendCharacter)
                                            If structureAppendCharacter.SymbolCount = symbolsCount Then
                                                    readingResults(i).ShowNonDataFlagsInValue = False
                                                    resultValues(structureAppendCharacter.SymbolPosition - 1) = readingResults(i).Value
                                            End If
                                    End If
                            Next
    
                            ' build result string
                            Dim result As New StringBuilder()
                            For i As Integer = 0 To resultValues.Length - 1
                                    If resultValues(i) IsNot Nothing Then
                                            result.Append(resultValues(i))
                                    Else
                                            Throw New ApplicationException(String.Format("missing symbol at position {0}", i + 1))
                                    End If
                            Next
    
                            Return result.ToString()
                    End Using
            End Function
    
    End Class
                  
    
    using System;
    using System.Drawing;
    using System.Text;
    using Vintasoft.Barcode;
    using Vintasoft.Barcode.BarcodeInfo;
    
    /// <summary>
    /// Test that shows how to use Structured Append feature for distributing data message across
    /// several 2D barcodes.
    /// </summary>
    class StructureAppendExample
    {
    
        /// <summary>
        /// Runs the test.
        /// </summary>
        public static void Test()
        {
            BarcodeType barcodeType = BarcodeType.DataMatrix;
    
            int symbolsCount = 5;
    
            string symbolsValue =
                "In order to fit a non-square area or to handle larger messages than are practical " +
                "in a single symbol, a data message can be distributed across several symbols. " +
                "Aztec, Code 16K, DataMatrix, MaxiCode, QR Code, PDF417, Micro PDF417 "+
                "symbols may be appended in a structured format.";
    
            // split data and generate barcodes
            Image[] barcodeImages = GenerateBarcodes(barcodeType, symbolsValue, symbolsCount);
    
            // resort barcode images
            Array.Reverse(barcodeImages);
            Array.Reverse(barcodeImages, 0, barcodeImages.Length / 2);
    
            // read barcodes and merge data value
            string readValue = ReadBarcodeValue(barcodeImages, barcodeType);
    
            if (readValue == symbolsValue)
                Console.WriteLine("Success");
            else
                throw new ApplicationException();
        }
    
        /// <summary>
        /// Splits value and generates symbolCount barcodes using Structured Append.
        /// </summary>
        public static Image[] GenerateBarcodes(BarcodeType barcodeType, string value, int symbolCount)
        {
            // create an image array
            Image[] result = new Image[symbolCount];
    
            // create the barcode writer
            BarcodeWriter writer = new BarcodeWriter();        
            
            // specify that writer must generate barcode of specified type
            writer.Settings.Barcode = barcodeType;
    
            // create parity data for a QR barcode value
            byte parityData = 0;
            if (barcodeType == BarcodeType.QR)
                parityData = QRStructuredAppendCharacter.CaluculateParityData(value);
    
            // generate symbols(barcodes)
            int fragmentLength = value.Length / symbolCount;
            for (int i = 0; i < symbolCount; i++)
            {
                // create Structured Append character
    
                StructuredAppendCharacter structureAppendCharacter;
                switch (barcodeType)
                {
                    case BarcodeType.Aztec:
                        structureAppendCharacter =
                            new AztecStructuredAppendCharacter(i + 1, symbolCount, "");
                        break;
    
                    case BarcodeType.DataMatrix:
                        structureAppendCharacter =
                            new DataMatrixStructuredAppendCharacter(i + 1, symbolCount, 0);
                        break;
    
                    case BarcodeType.QR:
                        structureAppendCharacter =
                            new QRStructuredAppendCharacter(i + 1, symbolCount, parityData);
                        break;
                    
                    case BarcodeType.Code16K:
                        structureAppendCharacter =
                            new StructuredAppendCharacter(i + 1, symbolCount);
                        writer.Settings.Height = 200;
                        break;
    
                    case BarcodeType.MaxiCode:
                        structureAppendCharacter =
                            new StructuredAppendCharacter(i + 1, symbolCount);
                        break;
    
                    case BarcodeType.MicroPDF417:
                        structureAppendCharacter =
                            new PDF417StructuredAppendCharacter(i + 1, symbolCount, "123");
                        break;
    
                    case BarcodeType.PDF417:
                        structureAppendCharacter =
                            new PDF417StructuredAppendCharacter(i + 1, symbolCount, "123");
                        break;
    
                    default:
                        throw new NotSupportedException();
                }
    
                // create symbol data
    
                string symbolTextData;
                if (i == symbolCount - 1)
                    symbolTextData = value.Substring(i * fragmentLength);
                else
                    symbolTextData = value.Substring(i * fragmentLength, fragmentLength);
                
                TextValueItem symbolData = new TextValueItem(symbolTextData);
    
                // set the barcode value items
                writer.Settings.ValueItems = new ValueItemBase[] { structureAppendCharacter, symbolData };
                
                // create image with barcode
                result[i] = writer.GetBarcodeAsBitmap();
            }
    
            return result;
        }
    
        /// <summary>
        /// Reads barcodes and merges the results into a single value.
        /// </summary>
        private static string ReadBarcodeValue(Image[] barcodeImages, BarcodeType barcodeType)
        {
            // create the barcode reader
            using (BarcodeReader reader = new BarcodeReader())
            {
                // specify that reader must search for barcodes of specified type
                reader.Settings.ScanBarcodeTypes = barcodeType;
    
                // barcode reading results
                IBarcodeInfo[] readingResults = new IBarcodeInfo[barcodeImages.Length];
                // read barcodes
                for (int i = 0; i < barcodeImages.Length; i++)
                {
                    // read barcode from image
                    readingResults[i] = reader.ReadBarcodes(barcodeImages[i])[0];
    
                    // dispose image
                    barcodeImages[i].Dispose();
                }
    
                // determine symbol count
                int symbolsCount = 0;
                for (int i = 0; i < readingResults.Length; i++)
                {
                    if (readingResults[i].ValueItems[0] is StructuredAppendCharacter)
                    {
                        symbolsCount = ((StructuredAppendCharacter)readingResults[i].ValueItems[0]).SymbolCount;
                        break;
                    }
                }
                if (symbolsCount == 0)
                    throw new ApplicationException("No Structured Append symbols.");
    
                // create array of string
                string[] resultValues = new string[symbolsCount];
                // fill resultValues
                for (int i = 0; i < readingResults.Length; i++)
                {
                    if (readingResults[i].ValueItems[0] is StructuredAppendCharacter)
                    {
                        StructuredAppendCharacter structureAppendCharacter =
                            (StructuredAppendCharacter)readingResults[i].ValueItems[0];
                        if (structureAppendCharacter.SymbolCount == symbolsCount)
                        {
                            readingResults[i].ShowNonDataFlagsInValue = false;
                            resultValues[structureAppendCharacter.SymbolPosition - 1] = readingResults[i].Value;
                        }
                    }
                }
    
                // build result string
                StringBuilder result = new StringBuilder();
                for (int i = 0; i < resultValues.Length; i++)
                {
                    if (resultValues[i] != null)
                    {
                        result.Append(resultValues[i]);
                    }
                    else
                    {
                        throw new ApplicationException(string.Format("missing symbol at position {0}", i + 1));
                    }
                }
    
                return result.ToString();
            }
        }
    
    }