VintaSoft Barcode .NET SDK 16.0: Руководство для .NET разработчика
В этом разделе
Как использовать функционал Structure Append для распределения сообщения данных по нескольким 2D штрих-кодам?
В этом разделе
Функционал "Structure Append" позволяет распределить сообщение данных по нескольким 2D штрих-кодам (до 16 штрих-кодов DataMatrix, до 16 штрих-кодов QR, до 26 штрих-кодов Aztec, до 99999 штрих-кодов PDF417, до 9 штрих-кодов Code16K, до 35 штрих-кодов DotCode), если сообщение с данными не может быть сохранено в одном 2D штрих-коде.

Вот пример C#/VB.NET кода, который показывает, как использовать функционал "Structure Append" для распределения сообщения данных по нескольким 2D штрих-кодам.
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();
        }
    }

}

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