跳至页脚内容
USING IRONBARCODE

How to Build a Barcode Scanner API in C# Using IronBarcode

在.NET中构建C#扫描器API传统上需要复杂的扫描器SDK集成或有限的软件库。 使用IronBarcode,开发人员可以在几分钟内创建一个强大的、生产就绪的条码扫描器API。 这些可以轻松从图像、PDF,甚至是受损的扫描输入中处理条码数据

本教程演示了如何使用ASP.NET Core在Windows上构建RESTful扫描器API,为硬件扫描器设备提供了可扩展的替代方案,同时保持企业级的准确性。 该API能够处理多种扫描器类型,处理二进制数据,并从任何支持的矩阵或表格格式中提取条码值。

我如何安装和设置IronBarcode?

开始使用IronBarcode就像安装一个NuGet包一样简单。 打开你的ASP.NET Core项目,并在包管理器控制台中运行此命令:

Install-Package BarCode

安装后,向控制器添加IronBarcode命名空间,并用这个单行示例来测试库:

using IronBarCode;
// Simple test to verify installation
var result = BarcodeReader.Read("test-barcode.png");
Console.WriteLine($"Scanned: {result.First().Value}");
using IronBarCode;
// Simple test to verify installation
var result = BarcodeReader.Read("test-barcode.png");
Console.WriteLine($"Scanned: {result.First().Value}");
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

这段代码读取一个条码图像并输出其值。 BarcodeReader.Read()方法自动检测条码格式并返回结果集,使从任何支持的图像(jpeg、bmp、png、tiff)提取条码数据和处理数组或二进制数据格式变得非常简单。

我如何构建一个完整的扫描器API控制器?

用ASP.NET Core创建扫描器API涉及设置一个接收各种输入源参数的控制器。 这里是一个完整的实现:

using Microsoft.AspNetCore.Mvc;
using IronBarCode;
using System.Drawing;
namespace BarcodeScannerAPI.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ScannerController : ControllerBase
    {
        // Model for API responses
        public class ScanResult
        {
            public bool Success { get; set; }
            public List<string> BarcodeValues { get; set; } = new List<string>();
            public string BarcodeFormat { get; set; }
            public string ErrorMessage { get; set; }
        }
        [HttpPost("scan-file")]
        public async Task<ActionResult<ScanResult>> ScanFile(IFormFile file)
        {
            if (file == null || file.Length == 0)
                return BadRequest(new ScanResult
                {
                    Success = false,
                    ErrorMessage = "No file uploaded"
                });
            try
            {
                using var stream = new MemoryStream();
                await file.CopyToAsync(stream);
                // Configure scanner options for better accuracy
                var options = new BarcodeReaderOptions
                {
                    Speed = ReadingSpeed.Balanced,
                    ExpectMultipleBarcodes = true,
                    ExpectBarcodeTypes = BarcodeEncoding.All
                };
                // Read barcodes from the uploaded file
                var results = BarcodeReader.Read(stream.ToArray(), options);
                if (results.Any())
                {
                    return Ok(new ScanResult
                    {
                        Success = true,
                        BarcodeValues = results.Select(r => r.Value).ToList(),
                        BarcodeFormat = results.First().BarcodeType.ToString()
                    });
                }
                return Ok(new ScanResult
                {
                    Success = false,
                    ErrorMessage = "No barcodes found"
                });
            }
            catch (Exception ex)
            {
                return StatusCode(500, new ScanResult
                {
                    Success = false,
                    ErrorMessage = $"Processing error: {ex.Message}"
                });
            }
        }
        [HttpPost("scan-base64")]
        public ActionResult<ScanResult> ScanBase64([FromBody] string base64Image)
        {
            try
            {
                // Convert Base64 string to byte array
                byte[] imageBytes = Convert.FromBase64String(base64Image);
                // Process with IronBarcode
                var results = BarcodeReader.Read(imageBytes);
                return ProcessResults(results);
            }
            catch (Exception ex)
            {
                return BadRequest(new ScanResult
                {
                    Success = false,
                    ErrorMessage = $"Invalid Base64 data: {ex.Message}"
                });
            }
        }
        private ScanResult ProcessResults(BarcodeResults results)
        {
            if (results.Any())
            {
                return new ScanResult
                {
                    Success = true,
                    BarcodeValues = results.Select(r => r.Value).ToList(),
                    BarcodeFormat = results.First().BarcodeType.ToString()
                };
            }
            return new ScanResult
            {
                Success = false,
                ErrorMessage = "No barcodes detected"
            };
        }
    }
}
using Microsoft.AspNetCore.Mvc;
using IronBarCode;
using System.Drawing;
namespace BarcodeScannerAPI.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ScannerController : ControllerBase
    {
        // Model for API responses
        public class ScanResult
        {
            public bool Success { get; set; }
            public List<string> BarcodeValues { get; set; } = new List<string>();
            public string BarcodeFormat { get; set; }
            public string ErrorMessage { get; set; }
        }
        [HttpPost("scan-file")]
        public async Task<ActionResult<ScanResult>> ScanFile(IFormFile file)
        {
            if (file == null || file.Length == 0)
                return BadRequest(new ScanResult
                {
                    Success = false,
                    ErrorMessage = "No file uploaded"
                });
            try
            {
                using var stream = new MemoryStream();
                await file.CopyToAsync(stream);
                // Configure scanner options for better accuracy
                var options = new BarcodeReaderOptions
                {
                    Speed = ReadingSpeed.Balanced,
                    ExpectMultipleBarcodes = true,
                    ExpectBarcodeTypes = BarcodeEncoding.All
                };
                // Read barcodes from the uploaded file
                var results = BarcodeReader.Read(stream.ToArray(), options);
                if (results.Any())
                {
                    return Ok(new ScanResult
                    {
                        Success = true,
                        BarcodeValues = results.Select(r => r.Value).ToList(),
                        BarcodeFormat = results.First().BarcodeType.ToString()
                    });
                }
                return Ok(new ScanResult
                {
                    Success = false,
                    ErrorMessage = "No barcodes found"
                });
            }
            catch (Exception ex)
            {
                return StatusCode(500, new ScanResult
                {
                    Success = false,
                    ErrorMessage = $"Processing error: {ex.Message}"
                });
            }
        }
        [HttpPost("scan-base64")]
        public ActionResult<ScanResult> ScanBase64([FromBody] string base64Image)
        {
            try
            {
                // Convert Base64 string to byte array
                byte[] imageBytes = Convert.FromBase64String(base64Image);
                // Process with IronBarcode
                var results = BarcodeReader.Read(imageBytes);
                return ProcessResults(results);
            }
            catch (Exception ex)
            {
                return BadRequest(new ScanResult
                {
                    Success = false,
                    ErrorMessage = $"Invalid Base64 data: {ex.Message}"
                });
            }
        }
        private ScanResult ProcessResults(BarcodeResults results)
        {
            if (results.Any())
            {
                return new ScanResult
                {
                    Success = true,
                    BarcodeValues = results.Select(r => r.Value).ToList(),
                    BarcodeFormat = results.First().BarcodeType.ToString()
                };
            }
            return new ScanResult
            {
                Success = false,
                ErrorMessage = "No barcodes detected"
            };
        }
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

这个控制器提供两个端点:一个用于文件上传,另一个用于Base64编码的图像。 ScanFile端点接受多部分表单数据,非常适合用户直接上传图像的Web应用程序。 流处理确保了内存使用的效率,而BarcodeReaderOptions配置在速度和准确性之间取得平衡。

ScanBase64端点处理图像以Base64字符串形式传输的场景,这是移动应用程序和API到API通信中的标准。 它能够从上传的图像或流中读取一维和二维(矩阵)条码。

输出

首先,我们使用Swagger来测试我们的端点。 在这里,你可以看到扫描器API端点:

如何使用IronBarcode在C#中构建条码扫描器API:图1 - 带有API端点的Swagger UI

现在,我们来测试它们并查看输出。 在这个例子中,我会用一个简单的字符串值"Hello World"编码的样品条码图像。 正如你在这里看到的,我们的程序已正确扫描了条码并检索了其中的数据。

如何使用IronBarcode在C#中构建条码扫描器API:图2 - 简单条码扫描输出

扫描器能处理哪些不同的输入源?

IronBarcode在处理各种输入格式时表现出灵活性。 除了标准图像,扫描器API还处理PDF、上传流和多种图形格式:

// Scanning PDFs with multiple pages
[HttpPost("scan-pdf")]
public async Task<ActionResult<ScanResult>> ScanPdf(IFormFile pdfFile
{
    using var stream = new MemoryStream();
    await pdfFile.CopyToAsync(stream);
    // ReadPdf method handles multi-page documents
    var results = BarcodeReader.ReadPdf(stream.ToArray());
    return ProcessResults(results);
}
// Processing from URL
[HttpPost("scan-url")]
public async Task<ActionResult<ScanResult>> ScanFromUrl([FromBody] string imageUrl)
{
    using var client = new HttpClient();
    var imageBytes = await client.GetByteArrayAsync(imageUrl);
    var results = BarcodeReader.Read(imageBytes);
    return ProcessResults(results);
}
// Scanning PDFs with multiple pages
[HttpPost("scan-pdf")]
public async Task<ActionResult<ScanResult>> ScanPdf(IFormFile pdfFile
{
    using var stream = new MemoryStream();
    await pdfFile.CopyToAsync(stream);
    // ReadPdf method handles multi-page documents
    var results = BarcodeReader.ReadPdf(stream.ToArray());
    return ProcessResults(results);
}
// Processing from URL
[HttpPost("scan-url")]
public async Task<ActionResult<ScanResult>> ScanFromUrl([FromBody] string imageUrl)
{
    using var client = new HttpClient();
    var imageBytes = await client.GetByteArrayAsync(imageUrl);
    var results = BarcodeReader.Read(imageBytes);
    return ProcessResults(results);
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

ReadPdf方法自动扫描PDF文档的所有页面,从运输标签、发票或多页报告中提取条码。 对于基于URL的扫描,API获取远程图像并处理它们,无需本地存储,理想地融合云存储服务或处理外部系统的图像。

现在,你可以看到更新后的Swagger UI,带有我们的新端点:

如何使用IronBarcode在C#中构建条码扫描器API:图3 - 更新的Swagger UI和两个新端点

为了测试我们的新方法,我使用了一个包含两个条码样本的PDF。

如何使用IronBarcode在C#中构建条码扫描器API:图4 - 样品PDF

第一个是带有URL的基本条码,第二个是我们最后一个例子中的基本字符串编码条码。 这是通过端点运行我们PDF时的输出:

如何使用IronBarcode在C#中构建条码扫描器API:图5 - 扫描PDF带有条码输出

正如你所见,它已正确检测到两个条码并从扫描的条码中提取了数据。

优化条码扫描器的性能和准确性

为特定用例微调扫描器显著提升了速度和准确性:

var optimizedOptions = new BarcodeReaderOptions
{
    // Speed settings: Faster, Balanced, Detailed, ExtremeDetail
    Speed = ReadingSpeed.Detailed,
    // Specify expected barcode types to reduce processing time
    ExpectBarcodeTypes = BarcodeEncoding.QRCode | BarcodeEncoding.Code128,
    // Enable parallel processing for batch operations
    Multithreaded = true,
    MaxParallelThreads = 4,
    // Define scanning area to focus on specific regions
    CropArea = new Rectangle(100, 100, 400, 200), // Optional: define specific scanning area
    // Apply image corrections for damaged barcodes
    ImageFilters = new ImageFilterCollection() { 
        new SharpenFilter(),
        new ContrastFilter() 
    }
};
var optimizedOptions = new BarcodeReaderOptions
{
    // Speed settings: Faster, Balanced, Detailed, ExtremeDetail
    Speed = ReadingSpeed.Detailed,
    // Specify expected barcode types to reduce processing time
    ExpectBarcodeTypes = BarcodeEncoding.QRCode | BarcodeEncoding.Code128,
    // Enable parallel processing for batch operations
    Multithreaded = true,
    MaxParallelThreads = 4,
    // Define scanning area to focus on specific regions
    CropArea = new Rectangle(100, 100, 400, 200), // Optional: define specific scanning area
    // Apply image corrections for damaged barcodes
    ImageFilters = new ImageFilterCollection() { 
        new SharpenFilter(),
        new ContrastFilter() 
    }
};
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

注意:CropArea属性允许扫描器在图像中专注于特定的矩阵或表格区域。 然而,一些对象或条码位置可能落在定义区域之外,导致扫描器失败。 如果发生这种情况,只需删除或注释掉CropArea属性。 IronBarcode将识别并解码默认完整图像中的所有条码数据,确保扫描器能够处理任何Windows或Microsoft运行时环境。

为已知的扫描器类型使用优化的选项可减少处理时间。嵌入式图像滤镜增强了低质量输入的条码可读性。 开发人员可以配置扫描器SDK,枚举可用的扫描器,整合UI组件或视频捕捉设备。

摘要

使用IronBarcode构建C#扫描器API将复杂的条码处理转化为简单的REST端点。 该库从完美的数字条码到具有挑战性的现实世界捕获都能处理,提供企业级的准确性,而无需硬件依赖。

支持多种输入格式,高级图像校正和优化的性能设置,开发人员可以在几分钟内部署生产就绪的扫描解决方案。 Get started with a free trial to implement your scanner API today, or explore the complete 文档以获取高级特性,如批处理和机器学习驱动的检测。

常见问题解答

使用 IronBarcode 构建扫描器 API 的主要好处是什么?

IronBarcode 允许开发人员以最小的复杂性快速创建功能强大、可投入生产的条形码扫描器 API。它通过消除复杂的扫描器 SDK 集成来简化过程。

IronBarcode 可以处理损坏的条形码输入吗?

是的,IronBarcode 旨在即使在扫描输入损坏时也能处理条形码数据,从而确保在实际应用中的高可靠性。

IronBarcode 在 C# 扫描器 API 中可以处理哪些类型的输入?

IronBarcode 可以处理来自各种输入的条形码数据,如图像和 PDF,提供多样化的解决方案以满足不同的扫描需求。

是否有使用 IronBarcode 构建条形码扫描器 API 的教程?

是的,网页上提供了一个全面的教程,其中包含代码示例,以指导开发人员构建使用 IronBarcode 的 RESTful 条形码扫描端点。

使用 IronBarcode 可以多快设置条形码扫描器 API?

使用 IronBarcode,开发人员可以在几分钟内设置条形码扫描器 API,从而简化开发时间和精力。

IronBarcode 需要任何复杂的 SDK 集成吗?

不,IronBarcode 消除了复杂的扫描器 SDK 集成的需要,使开发人员更容易实现条形码扫描功能。

使用 IronBarcode 构建扫描器 API 使用哪种编程语言?

IronBarcode 与 C# 一起用于构建扫描器 API,利用 .NET 框架实现稳健的性能。

Jordi Bardia
软件工程师
Jordi 最擅长 Python、C# 和 C++,当他不在 Iron Software 利用这些技能时,他就在游戏编程。分享产品测试、产品开发和研究的责任,Jordi 在持续的产品改进中增加了巨大的价值。多样的经验使他面临挑战并保持投入,他表示这是在 Iron Software 工作的最喜欢的方面之一。Jordi 在佛罗里达州迈阿密长大,并在佛罗里达大学学习计算机科学和统计学。