VintaSoft Barcode .NET SDK 15.1: Documentation for .NET developer
Vintasoft.Barcode.BarcodeInfo Namespace / StructuredAppendCharacter Class
Members Object Syntax Remarks Example Hierarchy Requirements SeeAlso
In This Topic
    StructuredAppendCharacter Class
    In This Topic
    Contains information about the Structured Append non-data character.
    Object Model
    StructuredAppendCharacter
    Syntax
    'Declaration
    
    Public Class StructuredAppendCharacter
       Inherits NonDataFlagValueItem
    
    
    public class StructuredAppendCharacter : NonDataFlagValueItem
    
    
    public __gc class StructuredAppendCharacter : public NonDataFlagValueItem*
    
    
    public ref class StructuredAppendCharacter : public NonDataFlagValueItem^
    
    
    Remarks

    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 using Structured Append character.
    This character is available only in first position of Aztec, Code 16K, DataMatrix, MaxiCode, PDF417, Micro PDF417 and QR barcodes.

    Example

    This C#/VB.NET code shows how to write and read Structured Append character.

       
    Imports System.Text   
       
    Imports Vintasoft.Barcode   
    Imports Vintasoft.Barcode.BarcodeInfo   
    Imports Vintasoft.Imaging   
       
    ''' <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, DotCode, MaxiCode, QR Code, PDF417, Micro PDF417 " & "symbols may be appended in a structured format."   
       
            ' split data and generate barcodes
            Dim barcodeImages As VintasoftBitmap() = 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 VintasoftBitmap()   
            ' create an image array
            Dim result As VintasoftBitmap() = New VintasoftBitmap(symbolCount - 1) {}   
       
            ' create the barcode writer
            Using writer As New BarcodeWriter()   
                ' specify that writer must generate barcode of specified type
                writer.Settings.Barcode = barcodeType__1   
                writer.Settings.MinWidth = 5   
       
                ' 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.DotCode   
                            structureAppendCharacter = NonDataFlags.CreateDotCodeStructuredAppendCharacter(i + 1, symbolCount)   
                            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.GetBarcodeAsVintasoftBitmap()   
                Next   
       
                Return result   
            End Using   
        End Function   
       
        ''' <summary>
        ''' Reads barcodes and merges the results into a single value.
        ''' </summary>
        Private Shared Function ReadBarcodeValue(barcodeImages As VintasoftBitmap(), 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.Text;
    
    using Vintasoft.Barcode;
    using Vintasoft.Barcode.BarcodeInfo;
    using Vintasoft.Imaging;
    
    /// <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, DotCode, MaxiCode, QR Code, PDF417, Micro PDF417 "+
                "symbols may be appended in a structured format.";
    
            // split data and generate barcodes
            VintasoftBitmap[] 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 VintasoftBitmap[] GenerateBarcodes(BarcodeType barcodeType, string value, int symbolCount)
        {
            // create an image array
            VintasoftBitmap[] result = new VintasoftBitmap[symbolCount];
    
            // create the barcode writer
            using (BarcodeWriter writer = new BarcodeWriter())
            {
                // specify that writer must generate barcode of specified type
                writer.Settings.Barcode = barcodeType;
                writer.Settings.MinWidth = 5;
    
                // 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.DotCode:
                            structureAppendCharacter =
                                NonDataFlags.CreateDotCodeStructuredAppendCharacter(i + 1, symbolCount);
                            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.GetBarcodeAsVintasoftBitmap();
                }
    
                return result;
            }
        }
    
        /// <summary>
        /// Reads barcodes and merges the results into a single value.
        /// </summary>
        private static string ReadBarcodeValue(VintasoftBitmap[] 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();
            }
        }
    
    }
    
    

    Inheritance Hierarchy
    Requirements

    Target Platforms: .NET9; .NET 8; .NET 7; .NET 6; .NET Framework 4.8, 4.7, 4.6, 4.5, 4.0, 3.5

    See Also