Распознавание и генерация штрих-кодов PDF417 используя VintaSoft Barcode .NET SDK

Категория: Штрих-коды.NET

30 января 2026

VintaSoft Barcode .NET SDK это профессиональный кросс-платформенный SDK для Windows, Linux, macOS, который позволяет распознавать и генерировать штрих-коды PDF417 в .NET, WPF, Веб, MAUI. VintaSoft Barcode .NET SDK позволяет добавить функциональность распознавания и генерации штрих-кодов PDF147 в .NET приложение используя всего несколько строк кода.

Что такое штрих-код PDF417?

Штрих-код PDF417 - это высокоплотный, многослойный двухмерный штрих-код, который используется для хранения больших объемов данных (до 1850 символов или 1108 байт). Изобретенный в 1991 году, он широко используется для государственных удостоверений личности, посадочных талонов и в логистике. Он использует 4 полосы/4 пробела, 17-элементный шаблон на кодовое слово, поддерживает встроенную коррекцию ошибок и обеспечивает компактное и надежное хранение данных.

Вот изображение штрих-кода PDF417:


Штрих-код PDF417 поддерживает следующие режимы хранения данных:

В штрих-коде PDF417 используется алгоритм коррекции ошибок Reed-Solomon, что позволяет распознавать поврежденные штрих-коды.

Штрих-код PDF417 может кодировать следующие специальные символы:

Структура штрих-кода PDF417

Штрих-код PDF417 состоит из ряда модулей, которые можно разделить на 3 отдельных группы:



Каждый модуль начинается с сплошного черного столбца и заканчивается сплошным белым столбцом, чтобы можно было визуально увидеть, где начинается и заканчивается каждый модуль. Также есть пустое поле с обеих сторон штрих-кода, которое известно как тихая зона.

Стартовый и стоповый поисковые паттерны указывают начальную и конечную области штрих-кода. Они помогают сканеру штрих-кода обнаружить штрих-код, но не содержат никаких данных.

Левый и правый индикаторы содержат информацию о штрих-коде, например, количество строк в штрих-коде, уровень коррекции ошибок и т. д.

Модуль кодовых слов данных содержит данные штрих-кода. Размер штрих-кода PDF417 зависит от того, сколько данных закодировано. Модуль кодовых слов данных может содержать от 1 до 30 кодовых слов и от 3 до 90 строк. На рисунке выше модуль кодовых слов данных содержит 4 кодовых слова в строке, кодовые слова помечены фиолетовым цветом. На рисунке выше модуль кодовых слов данных состоит из 4 строк.

Каждое кодовое слово имеет длину 17 ячеек и состоит из 4 черных полос и 4 белых ячеек, отсюда и название PDF417. Каждое кодовое слово данных читается слева направо, сверху вниз.


Что такое штрих-код PDF417 Compact?

Штрих-код PDF417 Compact - это вариант штрих-кода PDF417 в котором для экономии места отсутствует правый индикатор и стоповый поисковый паттерн.
Вот изображение штрих-кода PDF417 Compact:



Что такое штрих-код Micro PDF417?

Штрих-код Micro PDF417 - это компактная версия штрих-кода PDF417. Штрих-код Micro PDF417 обычно используется в составе композитных кодов (например, GS1 DataBar) для маркировки продукции, документов и в здравоохранении:


Штрих-код Micro PDF417 поддерживает следующие режимы хранения данных:

Штрих-код Micro PDF417 поддерживает следующие специальные символы:

Что такое штрих-код AAMVA?

Штрих-код AAMVA (DL/ID Card Design Standard) - это штрих-код PDF417, который хранит информацию о водительском удостоверении. VintaSoft Barcode .NET SDK умеет генерировать и распознавать штрих-коды AAMVA.
Вот изображение штрих-кода AAMVA:



Что такое штрих-код "XFA Compressed PDF417"?

Штрих-код "XFA Compressed PDF417" - это штрих-код PDF417, который хранит в себе данные, которые сжаты в соответствии с спецификацией Adobe XFA. VintaSoft Barcode .NET SDK умеет генерировать и распознавать штрих-коды "XFA Compressed PDF417"
Вот изображение штрих-кода "XFA Compressed QR":



Специальный символ "Structure Append"

Штрих-код PDF417 поддерживает специальный символ "Structure Append", который позволяет разделить данные на несколько (до 99999) штрих-кодов PDF417. Символ "Structure Append" кодируется в штрих-коде и позволяет однозначно определить количество штрих-кодов-частей и их порядок.

Вот изображение штрих-кода PDF417 текстом "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.":

А вот 5 штрих-кодов PDF417 с тем же текстом, но меньшего размера. Эти 5 штрих-кодов PDF417 объединены в одно значение с помощью специального символа "Structure Append":

VintaSoft Barcode .NET SDK содержит алгоритм восстановления данных из набора штрих-кодов-частей PDF417, которые были разделены используя символ "Structure Append".


Какие штрих-коды PDF417 может распознать VintaSoft Barcode .NET SDK?

VintaSoft Barcode .NET SDK может распознать все типы штрих-кодов PDF417: PDF417, PDF417 Compact, Micro PDF417, AAMVA, XFA Compressed PDF417. При распознавании применяются уникальные алгоритмы, которые позволяют быстро распознавать штрих-коды в изображениях имеющих различные проблемы:



Вот C# код, который демонстрирует как распознать штрих-коды PDF417 в изображении, которое получено с камеры:
/// <summary>
/// Reads PDF417 barcodes from a <see cref="System.Drawing.Bitmap"/>.
/// </summary>
/// <param name="bitmap">A bitmap with barcodes.</param>
public static void ReadPdf417BarcodesFromBitmap(System.Drawing.Bitmap bitmap)
{
    // create barcode reader
    using (Vintasoft.Barcode.BarcodeReader reader = new Vintasoft.Barcode.BarcodeReader())
    {
        // specify that reader must search for PDF417 barcodes
        reader.Settings.ScanBarcodeTypes = Vintasoft.Barcode.BarcodeType.PDF417;

        // read barcodes from image
        Vintasoft.Barcode.IBarcodeInfo[] infos = Vintasoft.Barcode.GdiExtensions.ReadBarcodes(reader, bitmap);

        // if barcodes are not detected
        if (infos.Length == 0)
        {
            System.Console.WriteLine("No barcodes found.");
        }
        // if barcodes are detected
        else
        {
            // get information about extracted barcodes

            System.Console.WriteLine(string.Format("{0} barcodes found:", infos.Length));
            System.Console.WriteLine();
            for (int i = 0; i < infos.Length; i++)
            {
                Vintasoft.Barcode.IBarcodeInfo info = infos[i];
                System.Console.WriteLine(string.Format("[{0}:{1}]", i + 1, info.BarcodeType));
                System.Console.WriteLine(string.Format("Value:      {0}", info.Value));
                System.Console.WriteLine(string.Format("Region:     {0}", info.Region));
                System.Console.WriteLine();
            }
        }
    }
}


Вот C# код, который демонстрирует как сгенерировать и распознать штрих-код AAMVA:
/// <summary>
/// Generates and recognizes AAMVA barcode.
/// </summary>
public static void GenerateAndRecognizeAamvaBarcode()
{
    // create DL data elements
    AamvaDataElement[] dlElements = new AamvaDataElement[] {
        new AamvaDataElement(AamvaDataElementIdentifiers.DAQ, "C12345678"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DCS, "CARPENTER"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DDE, "N"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DAC, "JON"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DDF, "N"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DAD, "T"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DDG, "N"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DCA, "D"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DCB, "1"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DCD, "NONE"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DBD, "10052015"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DBB, "07241984"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DBA, "01092022"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DBC, "1"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DAU, "067 in"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DAY, "BLK"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DAG, "3211 SANCTUARY LANE"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DAI, "LOUISVILLE"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DAJ, "KY"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DAK, "123454321"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DCF, "9876543210123456"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DCG, "USA"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DCK, "1234567890123456"),
        new AamvaDataElement(AamvaDataElementIdentifiers.DDB, "01062016")
    };

    // create ZK data elements
    AamvaDataElement[] zkElements = new AamvaDataElement[] {
        new AamvaDataElement("ZKA", "Y"),
        new AamvaDataElement("ZKB", "TEST"),
        new AamvaDataElement("ZKC", "9876"),
        new AamvaDataElement("ZKD", "DUP"),
    };

    // create subfiles
    AamvaSubfile[] subfiles = new AamvaSubfile[]{
        new AamvaSubfile("DL", dlElements),
        new AamvaSubfile("ZK", zkElements)
    };
    
    // create AAMVA barcode value
    AamvaBarcodeValue barcodeValue = new AamvaBarcodeValue(AamvaVersionLevel.AAMVA2016, 636046, 0, subfiles);
    
    // generate barcode image
    using (VintasoftBitmap barcodeImage = GenerateAamvaBarcode(barcodeValue))
    {
        // recognize barcode value
        AamvaBarcodeInfo recognizedBarcode = RecognizeAamvaBarcode(barcodeImage);

        // check value
        if (barcodeValue.ToString() != recognizedBarcode.AamvaValue.ToString())
            throw new ApplicationException();

        // print value
        Console.WriteLine("Version:         {0}", recognizedBarcode.VersionLevel);
        Console.WriteLine("Country:         {0}", recognizedBarcode.CountryId);
        Console.WriteLine("IIN:             {0}", recognizedBarcode.IssuerIdentificationNumber);
        Console.WriteLine("License number:  {0}", recognizedBarcode.LicenseNumber);
        Console.WriteLine("First name:      {0}", recognizedBarcode.FirstName);
        Console.WriteLine("Family name:     {0}", recognizedBarcode.FamilyName);
        Console.WriteLine("Middle name:     {0}", recognizedBarcode.MiddleName);
        Console.WriteLine("Sex (1=M;2=F):   {0}", recognizedBarcode.Sex);
        Console.WriteLine("Eye color:       {0}", recognizedBarcode.EyeColor);            
        Console.WriteLine("Date of birth:   {0}", recognizedBarcode.DateOfBirth.ToShortDateString());
        Console.WriteLine("Issue date:      {0}", recognizedBarcode.IssueDate.ToShortDateString());
        Console.WriteLine("Expiration date: {0}", recognizedBarcode.ExpirationDate.ToShortDateString());
        Console.WriteLine("State code:      {0}", recognizedBarcode.AddressStateCode);
        Console.WriteLine("City:            {0}", recognizedBarcode.AddressCity);
        Console.WriteLine("Postal code:     {0}", recognizedBarcode.AddressPostalCode);
        Console.WriteLine("Street:          {0}", recognizedBarcode.AddressStreet1);
        Console.WriteLine();
        Console.WriteLine("Data elements:");
        foreach (AamvaSubfile subfile in recognizedBarcode.Subfiles)
        {
            Console.WriteLine("[{0}] subfile:", subfile.SubfileType);
            foreach (AamvaDataElement dataElement in subfile.DataElements)
            {
                if (dataElement.Identifier.VersionLevel != AamvaVersionLevel.Undefined)
                    Console.Write("  [{0}] {1}:", dataElement.Identifier.ID, dataElement.Identifier.Description);
                else
                    Console.Write("  [{0}]:", dataElement.Identifier.ID);
                Console.WriteLine(" {0}", dataElement.Value);
            }
        }
    }
}

/// <summary>
/// Generates the AAMVA barcode image.
/// </summary>
/// <param name="barcodeValue">The barcode value.</param>
private static VintasoftBitmap GenerateAamvaBarcode(AamvaBarcodeValue barcodeValue)
{
    // create barcode writer
    using (BarcodeWriter writer = new BarcodeWriter())
    {
        // encode AAMVA barcode to writer settings
        BarcodeSymbologySubsets.AAMVA.Encode(barcodeValue, writer.Settings);

        // generate barcode image
        return writer.GetBarcodeAsVintasoftBitmap();
    }
}

/// <summary>
/// Recognizes the AAMVA barcode from image.
/// </summary>
/// <param name="barcodeImage">The barcode image.</param>
private static AamvaBarcodeInfo RecognizeAamvaBarcode(VintasoftBitmap barcodeImage)
{
    // create barcode reader
    using (BarcodeReader reader = new BarcodeReader())
    {
        // specify that AAMVA barcode must be recognized
        reader.Settings.ScanBarcodeSubsets.Add(BarcodeSymbologySubsets.AAMVA);

        // recognize barcodes
        IBarcodeInfo info = reader.ReadBarcodes(barcodeImage)[0];

        // return information about recognized AAMVA barcode
        return (AamvaBarcodeInfo)info;
    }
}


Вот C# код, который демонстрирует как сгенерировать и распознать штрих-код PDF417, который хранит в себе данные сжатые в соответствии с спецификацией Adobe XFA:
/// <summary>
/// Generates PDF417 barcode with XFA compression.
/// </summary>
public void GeneratePdf417BarcodeWithXfaCompression()
{
    string barcodeText =
        "https://www.vintasoft.com/vsbarcode-dotnet-index.html" + System.Environment.NewLine +
        "https://www.vintasoft.com/vstwain-dotnet-index.html" + System.Environment.NewLine +
        "https://www.vintasoft.com/vstwain-index.html" + System.Environment.NewLine +
        "https://www.vintasoft.com/vsimaging-dotnet-index.html" + System.Environment.NewLine +
        "https://www.vintasoft.com/vsannotation-dotnet-index.html" + System.Environment.NewLine +
        "https://www.vintasoft.com/vspdf-dotnet-index.html" + System.Environment.NewLine +
        "https://www.vintasoft.com/vsjbig2-dotnet-index.html" + System.Environment.NewLine +
        "https://www.vintasoft.com/vsjpeg2000-dotnet-index.html" + System.Environment.NewLine +
        "https://www.vintasoft.com/vsdoccleanup-dotnet-index.html" + System.Environment.NewLine +
        "https://www.vintasoft.com/vsocr-dotnet-index.html" + System.Environment.NewLine +
        "https://www.vintasoft.com/vsdicom-dotnet-index.html" + System.Environment.NewLine +
        "https://www.vintasoft.com/vsformsprocessing-dotnet-index.html" + System.Environment.NewLine +
        "https://www.vintasoft.com/vsoffice-dotnet-index.html";

    // create the barcode writer
    using (Vintasoft.Barcode.BarcodeWriter barcodeWriter = new Vintasoft.Barcode.BarcodeWriter())
    {
        // create the XFA compressed PDF417 barcode symbology
        Vintasoft.Barcode.SymbologySubsets.XFACompressedPDF417BarcodeSymbology xfaCompressedPdf417BarcodeSymbology =
            new Vintasoft.Barcode.SymbologySubsets.XFACompressedPDF417BarcodeSymbology();
        // encode barcode text using XFA compressed PDF417 barcode symbology
        xfaCompressedPdf417BarcodeSymbology.Encode(barcodeText, barcodeWriter.Settings);

        // save the barcode image to a file
        barcodeWriter.SaveBarcodeAsImage("pdf417-barcode-with-xfa-compression.png");
    }
}

/// <summary>
/// Recognizes PDF417 barcode with XFA compression.
/// </summary>
public void RecognizePdf417BarcodeWithXfaCompression()
{
    // create barcode reader
    using (Vintasoft.Barcode.BarcodeReader reader = new Vintasoft.Barcode.BarcodeReader())
    {
        // specify that reader must search for XFA compressed PDF417 barcodes
        reader.Settings.ScanBarcodeSubsets.Add(Vintasoft.Barcode.SymbologySubsets.BarcodeSymbologySubsets.XFACompressedPDF417);

        // read barcodes from image file
        Vintasoft.Barcode.IBarcodeInfo[] barcodeInfos = reader.ReadBarcodes("pdf417-barcode-with-xfa-compression.png");

        // if barcodes are not detected
        if (barcodeInfos.Length == 0)
        {
            System.Console.WriteLine("Barcodes are not found.");
        }
        // if barcodes are detected
        else
        {
            // get information about recognized barcodes

            System.Console.WriteLine(string.Format("{0} barcode(s) found:", barcodeInfos.Length));
            System.Console.WriteLine();
            for (int i = 0; i < barcodeInfos.Length; i++)
            {
                Vintasoft.Barcode.IBarcodeInfo barcodeInfo = barcodeInfos[i];
                System.Console.WriteLine(string.Format("[{0}:{1}]", i + 1, barcodeInfo.BarcodeType));
                System.Console.WriteLine(string.Format("Value:      {0}", barcodeInfo.Value));
                System.Console.WriteLine(string.Format("Region:     {0}", barcodeInfo.Region));
                System.Console.WriteLine();
            }
        }
    }
}


Какие штрих-коды PDF417 может генерировать VintaSoft Barcode .NET SDK?

VintaSoft Barcode .NET SDK генерирует все типы штрих-кодов PDF417: PDF417, PDF417 Compact, Micro PDF417, AAMVA, XFA Compressed PDF417.

Вот C# код, который демонстрирует как сгенерировать растровое изображение штрих-кода PDF417:
/// <summary>
/// Returns the PDF417 barcode as <see cref="System.Drawing.Bitmap"/>.
/// </summary>
/// <param name="value">The barcode value.</param>
/// <returns>A <see cref="System.Drawing.Bitmap"/> object.</returns>
public static System.Drawing.Bitmap GetPdf417BarcodeAsBitmap(string value)
{
    // create the barcode writer
    using (Vintasoft.Barcode.BarcodeWriter barcodeWriter = new Vintasoft.Barcode.BarcodeWriter())
    {
        // set barcode writer settings
        barcodeWriter.Settings.Barcode = Vintasoft.Barcode.BarcodeType.PDF417;
        barcodeWriter.Settings.Value = value;

        // get a barcode image as System.Drawing.Bitmap
        return Vintasoft.Barcode.GdiExtensions.GetBarcodeAsBitmap(barcodeWriter);
    }
}


Вот C# код, который демонстрирует как сгенерировать растровое изображение штрих-кода Micro PDF417:
/// <summary>
/// Returns the Micro PDF417 barcode as <see cref="System.Drawing.Bitmap"/>.
/// </summary>
/// <param name="value">The barcode value.</param>
/// <returns>A <see cref="System.Drawing.Bitmap"/> object.</returns>
public static System.Drawing.Bitmap GetMicroPdf417BarcodeAsBitmap(string value)
{
    // create the barcode writer
    using (Vintasoft.Barcode.BarcodeWriter barcodeWriter = new Vintasoft.Barcode.BarcodeWriter())
    {
        // set barcode writer settings
        barcodeWriter.Settings.Barcode = Vintasoft.Barcode.BarcodeType.MicroPDF417;
        barcodeWriter.Settings.Value = value;

        // get a barcode image as System.Drawing.Bitmap
        return Vintasoft.Barcode.GdiExtensions.GetBarcodeAsBitmap(barcodeWriter);
    }
}


Вот C# код, который демонстрирует как сгенерировать векторное (SVG) изображение штрих-кода PDF417:
/// <summary>
/// Returns the PDF417 barcode in vector form as a SVG string.
/// </summary>
/// <param name="barcodeValue">Barcode value.</param>
public static void GetPdf417BarcodeAsSvgString(string barcodeValue)
{
    // create the barcode writer
    using (Vintasoft.Barcode.BarcodeWriter barcodeWriter = new Vintasoft.Barcode.BarcodeWriter())
    {
        // set barcode writer settings
        barcodeWriter.Settings.Barcode = Vintasoft.Barcode.BarcodeType.PDF417;
        barcodeWriter.Settings.Value = barcodeValue;

        // generate PDF417 barcode as a SVG string
        return barcodeWriter.GetBarcodeAsSvgFile();
    }
}