StructuredAppendCharacter Class
In This Topic
Contains information about the Structured Append non-data character.
Object Model
Syntax
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