Skip to footer content
USING IRONBARCODE

How to Build a Barcode Reader SDK in .NET?

IronBarcode allows .NET developers to add barcode reading capabilities to their applications with minimal code. It supports multiple formats, including 1D and 2D barcodes, various image sources, and offers high accuracy with machine learning-based detection for production environments.

Barcode scanning is crucial for many applications, from inventory management to retail and logistics. By integrating barcode reading into your .NET applications, you can simplify data capture, automate workflows, and improve efficiency. When evaluating barcode reader solutions, consider factors like supported formats, processing speed, and integration complexity. The IronBarcode library offers full cross-platform compatibility with exceptional fault tolerance features.

IronBarcode is an effective .NET library that simplifies working with barcodes. With this tool, you can read barcodes from images, streams, and PDF files, as well as generate QR codes using the C# QR Code Generator. This article shows you how to integrate barcode scanning into your .NET application, focusing on creating an API or Web App integration to expose barcode scanning functionality. The library supports various barcode formats including 1D and 2D barcodes, with advanced generating capabilities and styling options.

What Are the Best Use Cases for IronBarcode Integration?

IronBarcode excels in these scenarios:

How Do I Create a Barcode Reader SDK in .NET?

To create a barcode reader that can be exposed as a service in your application, integrate IronBarcode into a REST API or Web App. The architecture choice depends on your processing needs: single-image processing for occasional scans, batch processing for document workflows, or stream processing for continuous scanning applications. Here's an example using ASP.NET Core with proper thread safety considerations. The library's reading features include advanced image creation filters for optimal accuracy.

  1. Install the .NET library for reading barcodes in C# using NuGet packages
  2. Create a reusable barcode scanning class with proper error handling
  3. Develop methods for reading barcodes from different sources
  4. Integrate barcode image reading into your application using improve settings
  5. Test and improve performance with reading speed options

What Do I Need Before Starting?

If you haven't already, download IronBarcode for your project. Make sure you have the proper license key for your intended use. Note that exposing IronBarcode's functionality via a public API or reselling it as a standalone service requires additional licensing (SDK, OEM, or SaaS). Ensure you understand the licensing options before proceeding. For development environments, you can start with the free trial and apply your license key when ready for production. Review the changelog for the latest updates and milestones.

For optimal performance, consider your deployment environment. IronBarcode supports cross-platform compatibility including Windows, Linux, macOS, Docker, and cloud platforms like Azure and AWS Lambda. Mobile developers can use support for Android and iOS through Blazor integration. For .NET MAUI applications, follow the barcode scanner reader tutorial.

How Do I Create a Barcode Scanner Class?

Once you've set up IronBarcode and installed it in your project, you can create a reusable barcode scanner class that integrates IronBarcode's functionality and exposes it as an API endpoint. The implementation includes performance optimizations and image correction for challenging scenarios with orientation correction. Consider implementing crop regions for faster processing when barcode locations are predictable:

using IronBarCode;
using System.IO;
using System.Collections.Concurrent;
using System.Threading.Tasks;

namespace BarcodeIntegration
{
    public class BarcodeScanner
    {
        private static readonly ConcurrentDictionary<string, BarcodeReaderOptions> _optionsCache = new();

        static BarcodeScanner()
        {
            // Set the license key
            IronBarCode.License.LicenseKey = "Your-License-Key";
        }

        // Method to read a barcode from an image file with performance optimization
        public string ReadBarcodeFromImage(string imagePath, BarcodeReadingSpeed speed = BarcodeReadingSpeed.Balanced)
        {
            try
            {
                var options = GetCachedOptions(speed);
                // Try to read the barcode from the given image path
                var barcode = BarcodeReader.Read(imagePath, options);
                return barcode?.ToString() ?? "No Barcode Found"; // Return the barcode string or indicate no barcode was found
            }
            catch (Exception ex)
            {
                // Return an error message if an exception occurs
                return $"Error reading barcode: {ex.Message}";
            }
        }

        // Method to read a barcode from a stream (e.g., file upload or memory stream)
        public async Task<string> ReadBarcodeFromStreamAsync(Stream inputStream)
        {
            try
            {
                var options = GetCachedOptions(BarcodeReadingSpeed.Detailed);
                // Enable image correction for better accuracy
                options.ImageFilters = new[] { 
                    new SharpenFilter(), 
                    new ContrastFilter() 
                };

                // Try to read the barcode from the given stream
                var barcode = await Task.Run(() => BarcodeReader.Read(inputStream, options));
                return barcode?.ToString() ?? "No barcode found";
            }
            catch (Exception ex)
            {
                return $"Error reading barcode: {ex.Message}";
            }
        }

        // Method to read a barcode from a PDF file with batch processing support
        public async Task<List<string>> ReadBarcodesFromPdfAsync(string filePath)
        {
            try
            {
                var options = new BarcodeReaderOptions
                {
                    ExpectMultipleBarcodes = true,
                    Speed = BarcodeReadingSpeed.Detailed
                };

                // Try to read barcodes from the given PDF file path
                var barcodes = await Task.Run(() => BarcodeReader.ReadPdf(filePath, options));
                return barcodes.Select(b => b.ToString()).ToList();
            }
            catch (Exception ex)
            {
                return new List<string> { $"Error reading barcode: {ex.Message}" };
            }
        }

        // Cache reader options for performance
        private BarcodeReaderOptions GetCachedOptions(BarcodeReadingSpeed speed)
        {
            return _optionsCache.GetOrAdd(speed.ToString(), _ => new BarcodeReaderOptions
            {
                Speed = speed,
                AutoRotate = true,
                RemoveFalsePositive = true
            });
        }
    }
}
using IronBarCode;
using System.IO;
using System.Collections.Concurrent;
using System.Threading.Tasks;

namespace BarcodeIntegration
{
    public class BarcodeScanner
    {
        private static readonly ConcurrentDictionary<string, BarcodeReaderOptions> _optionsCache = new();

        static BarcodeScanner()
        {
            // Set the license key
            IronBarCode.License.LicenseKey = "Your-License-Key";
        }

        // Method to read a barcode from an image file with performance optimization
        public string ReadBarcodeFromImage(string imagePath, BarcodeReadingSpeed speed = BarcodeReadingSpeed.Balanced)
        {
            try
            {
                var options = GetCachedOptions(speed);
                // Try to read the barcode from the given image path
                var barcode = BarcodeReader.Read(imagePath, options);
                return barcode?.ToString() ?? "No Barcode Found"; // Return the barcode string or indicate no barcode was found
            }
            catch (Exception ex)
            {
                // Return an error message if an exception occurs
                return $"Error reading barcode: {ex.Message}";
            }
        }

        // Method to read a barcode from a stream (e.g., file upload or memory stream)
        public async Task<string> ReadBarcodeFromStreamAsync(Stream inputStream)
        {
            try
            {
                var options = GetCachedOptions(BarcodeReadingSpeed.Detailed);
                // Enable image correction for better accuracy
                options.ImageFilters = new[] { 
                    new SharpenFilter(), 
                    new ContrastFilter() 
                };

                // Try to read the barcode from the given stream
                var barcode = await Task.Run(() => BarcodeReader.Read(inputStream, options));
                return barcode?.ToString() ?? "No barcode found";
            }
            catch (Exception ex)
            {
                return $"Error reading barcode: {ex.Message}";
            }
        }

        // Method to read a barcode from a PDF file with batch processing support
        public async Task<List<string>> ReadBarcodesFromPdfAsync(string filePath)
        {
            try
            {
                var options = new BarcodeReaderOptions
                {
                    ExpectMultipleBarcodes = true,
                    Speed = BarcodeReadingSpeed.Detailed
                };

                // Try to read barcodes from the given PDF file path
                var barcodes = await Task.Run(() => BarcodeReader.ReadPdf(filePath, options));
                return barcodes.Select(b => b.ToString()).ToList();
            }
            catch (Exception ex)
            {
                return new List<string> { $"Error reading barcode: {ex.Message}" };
            }
        }

        // Cache reader options for performance
        private BarcodeReaderOptions GetCachedOptions(BarcodeReadingSpeed speed)
        {
            return _optionsCache.GetOrAdd(speed.ToString(), _ => new BarcodeReaderOptions
            {
                Speed = speed,
                AutoRotate = true,
                RemoveFalsePositive = true
            });
        }
    }
}
$vbLabelText   $csharpLabel

This improved BarcodeScanner class includes performance optimizations through options caching, async processing for better scalability, and image filters for improved accuracy. The implementation follows SOLID principles and provides production-ready error handling. For additional functionality, consider using System.Drawing integration or exporting as streams. You can also create barcode images with custom barcode styles and QR code styling.

Which Methods Should I Use to Read Different Barcode Sources?

Each method is improved for specific use cases and processing requirements:

  • ReadBarcodeFromImage(string imagePath): Reads a barcode from an image file.
  • ReadBarcodeFromStream(Stream inputStream): Reads a barcode from an input stream (e.g., file upload or memory stream).
  • ReadBarcodeFromPdf(string filePath): Reads a barcode from a PDF file.

For high-volume scenarios, consider using crop regions to improve processing speed by up to 5x when barcode locations are predictable. You can also create barcode images or save barcodes in various formats. The library supports reading from System.Drawing objects and can export barcodes as HTML or PDF documents.

How Do I Expose Barcode Reading via a REST API?

To allow external applications to use your barcode scanning functionality, expose it as a REST API using ASP.NET Core. The implementation includes proper error handling, validation, and support for multiple input formats. You can also generate barcodes with the C# Barcode Image Generator or explore barcode quickstart examples. When processing PDFs, consider stamping barcodes on existing PDFs for document tracking:

using Microsoft.AspNetCore.Mvc;
using System.IO;
using Microsoft.AspNetCore.Http;
using BarcodeIntegration;

[ApiController]
[Route("api/barcode")]
public class BarcodeController : ControllerBase
{
    private readonly BarcodeScanner _barcodeScanner;
    private readonly ILogger<BarcodeController> _logger;

    public BarcodeController(ILogger<BarcodeController> logger)
    {
        _barcodeScanner = new BarcodeScanner();
        _logger = logger;
    }

    // POST endpoint to read barcode from an uploaded image
    [HttpPost("read-from-image")]
    public async Task<IActionResult> ReadFromImage(IFormFile file)
    {
        if (file == null || file.Length == 0)
            return BadRequest(new { Error = "No file uploaded" });

        // Validate file type
        var allowedTypes = new[] { "image/jpeg", "image/png", "image/gif", "image/bmp", "image/tiff" };
        if (!allowedTypes.Contains(file.ContentType.ToLower()))
            return BadRequest(new { Error = "Unsupported file type" });

        try
        {
            using var stream = file.OpenReadStream();
            var result = await _barcodeScanner.ReadBarcodeFromStreamAsync(stream);

            _logger.LogInformation($"Barcode read successfully from {file.FileName}");
            return Ok(new { Barcode = result, FileName = file.FileName });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error processing barcode");
            return StatusCode(500, new { Error = "Internal server error" });
        }
    }

    // POST endpoint for batch processing
    [HttpPost("read-batch")]
    public async Task<IActionResult> ReadBatch(List<IFormFile> files)
    {
        var results = new List<object>();

        foreach (var file in files)
        {
            using var stream = file.OpenReadStream();
            var result = await _barcodeScanner.ReadBarcodeFromStreamAsync(stream);
            results.Add(new { FileName = file.FileName, Barcode = result });
        }

        return Ok(new { Results = results, Count = results.Count });
    }

    // POST endpoint to generate barcode from data
    [HttpPost("generate")]
    public IActionResult GenerateBarcode([FromBody] BarcodeGenerationRequest request)
    {
        try
        {
            // Create barcode with specified data and format
            var barcode = BarcodeWriter.CreateBarcode(request.Data, request.Format ?? BarcodeWriterEncoding.Code128);

            // Apply custom styling if requested
            if (request.Width.HasValue && request.Height.HasValue)
                barcode.ResizeTo(request.Width.Value, request.Height.Value);

            if (!string.IsNullOrEmpty(request.ForegroundColor))
                barcode.ChangeBarCodeColor(System.Drawing.ColorTranslator.FromHtml(request.ForegroundColor));

            // Return as base64 encoded image
            using var ms = barcode.ToStream();
            var bytes = ms.ToArray();
            return Ok(new { 
                Image = Convert.ToBase64String(bytes),
                Format = request.Format?.ToString() ?? "Code128",
                Data = request.Data 
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error generating barcode");
            return BadRequest(new { Error = "Failed to generate barcode" });
        }
    }
}

public class BarcodeGenerationRequest
{
    public string Data { get; set; }
    public BarcodeWriterEncoding? Format { get; set; }
    public int? Width { get; set; }
    public int? Height { get; set; }
    public string ForegroundColor { get; set; }
}
using Microsoft.AspNetCore.Mvc;
using System.IO;
using Microsoft.AspNetCore.Http;
using BarcodeIntegration;

[ApiController]
[Route("api/barcode")]
public class BarcodeController : ControllerBase
{
    private readonly BarcodeScanner _barcodeScanner;
    private readonly ILogger<BarcodeController> _logger;

    public BarcodeController(ILogger<BarcodeController> logger)
    {
        _barcodeScanner = new BarcodeScanner();
        _logger = logger;
    }

    // POST endpoint to read barcode from an uploaded image
    [HttpPost("read-from-image")]
    public async Task<IActionResult> ReadFromImage(IFormFile file)
    {
        if (file == null || file.Length == 0)
            return BadRequest(new { Error = "No file uploaded" });

        // Validate file type
        var allowedTypes = new[] { "image/jpeg", "image/png", "image/gif", "image/bmp", "image/tiff" };
        if (!allowedTypes.Contains(file.ContentType.ToLower()))
            return BadRequest(new { Error = "Unsupported file type" });

        try
        {
            using var stream = file.OpenReadStream();
            var result = await _barcodeScanner.ReadBarcodeFromStreamAsync(stream);

            _logger.LogInformation($"Barcode read successfully from {file.FileName}");
            return Ok(new { Barcode = result, FileName = file.FileName });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error processing barcode");
            return StatusCode(500, new { Error = "Internal server error" });
        }
    }

    // POST endpoint for batch processing
    [HttpPost("read-batch")]
    public async Task<IActionResult> ReadBatch(List<IFormFile> files)
    {
        var results = new List<object>();

        foreach (var file in files)
        {
            using var stream = file.OpenReadStream();
            var result = await _barcodeScanner.ReadBarcodeFromStreamAsync(stream);
            results.Add(new { FileName = file.FileName, Barcode = result });
        }

        return Ok(new { Results = results, Count = results.Count });
    }

    // POST endpoint to generate barcode from data
    [HttpPost("generate")]
    public IActionResult GenerateBarcode([FromBody] BarcodeGenerationRequest request)
    {
        try
        {
            // Create barcode with specified data and format
            var barcode = BarcodeWriter.CreateBarcode(request.Data, request.Format ?? BarcodeWriterEncoding.Code128);

            // Apply custom styling if requested
            if (request.Width.HasValue && request.Height.HasValue)
                barcode.ResizeTo(request.Width.Value, request.Height.Value);

            if (!string.IsNullOrEmpty(request.ForegroundColor))
                barcode.ChangeBarCodeColor(System.Drawing.ColorTranslator.FromHtml(request.ForegroundColor));

            // Return as base64 encoded image
            using var ms = barcode.ToStream();
            var bytes = ms.ToArray();
            return Ok(new { 
                Image = Convert.ToBase64String(bytes),
                Format = request.Format?.ToString() ?? "Code128",
                Data = request.Data 
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error generating barcode");
            return BadRequest(new { Error = "Failed to generate barcode" });
        }
    }
}

public class BarcodeGenerationRequest
{
    public string Data { get; set; }
    public BarcodeWriterEncoding? Format { get; set; }
    public int? Width { get; set; }
    public int? Height { get; set; }
    public string ForegroundColor { get; set; }
}
$vbLabelText   $csharpLabel

How Does the API Look in Swagger UI?

Swagger UI showing BarcoderScannerSDK API with two POST endpoints for barcode reading from images and PDFs, featuring file upload interface and request configuration options

What Does the API Response Look Like?

API documentation showing a successful POST request to a barcode reading endpoint that returns 'Hello World!' with a 200 OK response status

This API exposes POST endpoints where you can upload barcode images, and the API returns the barcode data. The implementation includes proper validation, error handling, and logging for production use. For mobile applications, consider adding endpoints improved for smaller image sizes and faster response times. You can also create barcodes from data or export them as HTML or PDF. For high-contrast requirements, generate 1-BPP barcode images.## What Advanced Features Can I Add?

To further improve your SDK, consider implementing these production-ready features using IronBarcode's complete API Reference. Explore the feature overview and check demos for practical implementations:

How Do I Support Multiple Barcode Types?

IronBarcode supports reading multiple barcodes simultaneously. You can configure your SDK to accept multiple barcodes at once with specific format filtering. The library supports writing Unicode barcodes including Chinese and Arabic characters. For specialized applications, explore Code 39 reading and create QR codes with custom styling:

public async Task<List<BarcodeResult>> ReadMultipleBarcodesAsync(string imagePath, BarcodeEncoding[] expectedTypes = null)
{
    try
    {
        var options = new BarcodeReaderOptions()
        {
            ExpectMultipleBarcodes = true,
            ExpectBarcodeTypes = expectedTypes ?? BarcodeEncoding.All,
            Speed = BarcodeReadingSpeed.Detailed,
            MaxParallelThreads = Environment.ProcessorCount,
            Multithreaded = true
        };

        // Apply confidence threshold for machine learning accuracy
        options.Confidence = Confidence.High;

        var results = await Task.Run(() => BarcodeReader.Read(imagePath, options));

        return results.Select(barcode => new BarcodeResult
        {
            Value = barcode.ToString(),
            Format = barcode.BarcodeType.ToString(),
            Confidence = barcode.Confidence,
            Position = barcode.Rect
        }).ToList();
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Error reading multiple barcodes");
        throw;
    }
}
public async Task<List<BarcodeResult>> ReadMultipleBarcodesAsync(string imagePath, BarcodeEncoding[] expectedTypes = null)
{
    try
    {
        var options = new BarcodeReaderOptions()
        {
            ExpectMultipleBarcodes = true,
            ExpectBarcodeTypes = expectedTypes ?? BarcodeEncoding.All,
            Speed = BarcodeReadingSpeed.Detailed,
            MaxParallelThreads = Environment.ProcessorCount,
            Multithreaded = true
        };

        // Apply confidence threshold for machine learning accuracy
        options.Confidence = Confidence.High;

        var results = await Task.Run(() => BarcodeReader.Read(imagePath, options));

        return results.Select(barcode => new BarcodeResult
        {
            Value = barcode.ToString(),
            Format = barcode.BarcodeType.ToString(),
            Confidence = barcode.Confidence,
            Position = barcode.Rect
        }).ToList();
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Error reading multiple barcodes");
        throw;
    }
}
$vbLabelText   $csharpLabel

What Other Improvements Should I Consider?

For production deployments, consider implementing confidence thresholds to reduce false positives and ensure data accuracy. The machine learning-based detection can be fine-tuned for your specific use case. When creating deployment packages, follow the MSI installer guide and address any missing DLL issues. For AWS deployments, be aware of potential runtime issues. Consider creating barcodes with various output data formats and explore barcode reading tutorials.

What Licensing Considerations Should I Be Aware Of?

As mentioned earlier, the IronBarcode SDK is meant for integration into your internal applications, and exposing it through an API requires additional licensing. You must secure the necessary licensing (SDK, OEM, or SaaS) before exposing IronBarcode as part of a service, such as a public API. For enterprise deployments, consider the licensing extensions available for additional seats or improve support. Review upgrade options for scaling your deployment.

Do not resell IronBarcode as a standalone SDK or expose it via a public-facing API without ensuring your licensing covers this usage. For web applications, you may need to configure the license key in web.config for proper activation. Stay informed about security CVE updates and follow best practices for runtime copy exceptions. For technical issues, consider submitting an engineering request. Check out resources on writing Unicode barcodes and explore the reading barcodes tutorial.

Why Should I Try IronBarcode Today?

Experience the new capabilities of IronBarcode. Try our free trial and discover smooth barcode generation, reading, and editing for your .NET applications. With advanced features, exceptional performance, and a user-friendly interface, IronBarcode is the ultimate solution for all your barcode needs. Explore our complete documentation, review code examples, and see live demos to understand the full capabilities. Check out tutorials on reading barcodes and explore MicroQR and rMQR support. Learn about NuGet package options for different deployment scenarios. You can also explore the IronBarcode Documentation for more information about our complete barcode solution. Start your free trial today and improve your projects.

Frequently Asked Questions

How can I integrate a barcode reader into a .NET application?

You can integrate a barcode reader into a .NET application by using the IronBarcode library. First, install IronBarcode, then create a class for barcode scanning, and implement methods to read barcodes from images, streams, and PDFs. Finally, test and optimize your setup.

How do I expose barcode reading functionality as a REST API?

To expose barcode reading functionality as a REST API, use ASP.NET Core to create a web application. Incorporate the IronBarcode library, develop a BarcodeScanner class, and define API endpoints that read barcodes using methods like ReadBarcodeFromImage and ReadBarcodeFromStream.

What barcode types can be read using a .NET barcode library?

A .NET barcode library like IronBarcode can read various barcode types including QR codes, Code 128, UPC, and EAN. You can configure the library to detect multiple barcode types simultaneously by setting detection parameters.

How can I handle errors when reading barcodes in .NET?

Handling errors in barcode reading can be achieved by implementing robust error handling within your barcode scanning methods using IronBarcode. Ensure you catch exceptions and provide meaningful feedback or retry mechanisms to improve the reliability of the barcode reading process.

What are the licensing requirements for using a .NET barcode library in a public API?

When using IronBarcode in a public API, you must ensure proper licensing. This includes obtaining SDK, OEM, or SaaS licenses, as exposing the library's functionality as a standalone service or public API requires additional permissions.

Can I batch process multiple barcode scans using a .NET library?

Yes, you can batch process multiple barcode scans using IronBarcode. The library allows you to read multiple barcodes in a single operation, which can be particularly useful for processing large sets of images or documents efficiently.

Is there a trial version available for a .NET barcode library?

Yes, IronBarcode offers a free trial version allowing you to explore its capabilities in barcode generation, reading, and editing within .NET applications. This trial can help you evaluate the library before making a purchasing decision.

Jordi Bardia
Software Engineer
Jordi is most proficient in Python, C# and C++, when he isn’t leveraging his skills at Iron Software; he’s game programming. Sharing responsibilities for product testing, product development and research, Jordi adds immense value to continual product improvement. The varied experience keeps him challenged and engaged, and he ...
Read More