Skaner kodów kreskowych ASP.NET: przesyłanie plików i API REST z IronBarcode
Skanowanie kodów kreskowych w ASP.NET staje się proste dzięki IronBarcode: zainstaluj za pomocą NuGet, wywołaj BarcodeReader.Read() i uzyskaj zdekodowane wartości wraz z danymi dotyczącymi typu, pewności i pozycji w jednym kroku — bez konieczności skomplikówanej konfiguracji.
Skanowanie BarCode jest standardowym wymaganiem w nowoczesnych aplikacjach internetowych, wspierającym zarządzanie zapasami, przetwarzanie dokumentów i procesy weryfikacji biletów. Według GS1 BarCODE'y są wykorzystywane codziennie w ponad 6 miliardach transakcji na całym świecie — liczba ta podkreśla, jak kluczowe znaczenie dla każdego systemu biznesowego ma dokładny odczyt BarCODE'ów. Norma ISO/IEC 15415 określa wskaźniki jakości dla symboli kodów kreskowych 2D, natomiast norma ISO/IEC 15416 dotyczy kodów kreskowych liniowych 1D. IronBarcode obsługuje oba te typy kodów w sposób natywny.
Ten przewodnik pokazuje, jak dodać niezawodne skanowanie kodów kreskowych do aplikacji ASP.NET Core przy użyciu IronBarcode, obejmując instalację, przetwarzanie przesyłania plików, integrację REST API oraz wzorce wdrażania produkcyjnego. Na koniec będziesz mieć działający kod zarówno dla skanera przesyłania plików na stronie Razor, jak i punktu końcowego API JSON, który akceptuje obrazy zakodowane w base64 z dowolnego klienta.
Jak zainstalować IronBarcode w projekcie ASP.NET?
Rozpoczęcie pracy zajmuje tylko kilka minut. Biblioteka obsługuje zarówno aplikacje .NET Core, jak i tradycyjne aplikacje ASP.NET MVC, dzięki czemu można ją dostosować do różnych typów projektów. Wdrożenia Enterprise działają równie dobrze na platformach Azure, AWS Lambda i w kontenerach Docker. Wykorzystujące uczenie maszynowe wykrywanie biblioteki radzi sobie z trudnymi obrazami BarCode poprzez automatyczne stosowanie zaawansowanej korekcji obrazu, co jest szczególnie przydatne podczas przetwarzania zdjęć wykonanych aparatami telefonów komórkowych w zmiennych warunkach oświetleniowych.
Instalacja za pomocą menedżera pakietów NuGet
Otwórz konsolę menedżera pakietów w Visual Studio i uruchom:
Install-Package BarCode
Install-Package BarCode
Alternatywnie można użyć interfejsu CLI platformy .NET:
dotnet add package BarCode
dotnet add package BarCode
Lub wyszukaj "BarCode" w interfejsie użytkownika menedżera pakietów NuGet programu Visual Studio i kliknij opcję Zainstaluj. Pakiet automatycznie zarządza wszystkimi zależnościami.
W przypadku wdrożeń specyficznych dla danej platformy warto rozważyć użycie pakietów NuGet zoptymalizowanych pod kątem docelowego środowiska. Biblioteka oferuje zarówno pakiety standardowe, jak i BarCode.Slim, dostosowane do różnych scenariuszy wdrożeniowych. Pełny opis instalacji znajduje się w przewodniku instalacji IronBarcode.
Konfiguracja projektu
Po zainstalowaniu dodaj niezbędną instrukcję using do plików C#:
using IronBarCode;
using IronBarCode;
Imports IronBarCode
Ten import zapewnia dostęp do pełnych możliwości IronBarcode w zakresie odczytu i generowania kodów kreskowych. Biblioteka obsługuje ponad 30 formatów BARCODE, w tym QR Code, Code 128, Code 39, Data Matrix i PDF417. Zapoznaj się z pełną listą obsługiwanych formatów BARCODE, aby sprawdzić zgodność z Twoim zastosowaniem.
W przypadku problemów z instalacją należy zapoznać się z przewodnikiem dotyczącym rozwiązywania problemów z pakietami NuGet lub złożyć zgłoszenie techniczne w celu uzyskania specjalistycznego wsparcia.
Wybór odpowiedniego wzorca architektury
Podczas wdrażania skanowania BarCode w ASP.NET dostępne są dwa główne podejścia architektoniczne. Zrozumienie tych wzorców pomoże Ci wybrać odpowiednie ustawienia czytnika BarCode dla każdego przypadku użycia:
// Server-side processing -- recommended for most ASP.NET scenarios
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
UseConfidenceThreshold = true,
ConfidenceThreshold = 0.85
};
var results = BarcodeReader.Read(stream, options);
foreach (var barcode in results)
{
Console.WriteLine($"Type: {barcode.BarcodeType}, Value: {barcode.Text}");
}
// Server-side processing -- recommended for most ASP.NET scenarios
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
UseConfidenceThreshold = true,
ConfidenceThreshold = 0.85
};
var results = BarcodeReader.Read(stream, options);
foreach (var barcode in results)
{
Console.WriteLine($"Type: {barcode.BarcodeType}, Value: {barcode.Text}");
}
Imports System
' Server-side processing -- recommended for most ASP.NET scenarios
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True,
.UseConfidenceThreshold = True,
.ConfidenceThreshold = 0.85
}
Dim results = BarcodeReader.Read(stream, options)
For Each barcode In results
Console.WriteLine($"Type: {barcode.BarcodeType}, Value: {barcode.Text}")
Next
Podejście po stronie serwera zapewnia maksymalną kontrolę nad przetwarzaniem obrazów i działa spójnie we wszystkich przeglądarkach. Gdy serwer przetwarza każdy obraz, otrzymujesz również przejrzystą ścieżkę audytu: każdy zeskanowany BarCode przechodzi przez warstwę aplikacji, gdzie możesz go zarejestrować, zweryfikować w bazie danych lub uruchomić dalsze procesy. Ten wzorzec szczególnie dobrze sprawdza się w branżach podlegających regulacjom, takich jak opieka zdrowotna, logistyka i produkcja, gdzie każde skanowanie musi być rejestrowane.
W przypadku integracji przechwytywania obrazu z kamery po stronie klienta nowoczesne przeglądarki obsługują interfejs API MediaDevices umożliwiający dostęp do kamery, który można połączyć z przetwarzaniem po stronie serwera w IronBarcode za pośrednictwem interfejsu API REST — co zostanie szczegółowo omówione w dalszej części tego przewodnika. Wybór przetwarzania po stronie serwera upraszcza również model bezpieczeństwa: żadna wrażliwa logika przetwarzania nie jest ujawniana przeglądarce, a cała walidacja odbywa się poza granicami aplikacji.
| Aspect | Przechwytywanie po stronie klienta + przetwarzanie na serwerze | Czyste przetwarzanie po stronie serwera |
|---|---|---|
| Najlepsze dla | Skanowanie w czasie rzeczywistym za pomocą kamery | Przetwarzanie wsadowe, przesyłanie plików |
| Obsługa przeglądarek | Tylko nowoczesne przeglądarki | Wszystkie przeglądarki |
| Doświadczenie użytkownika | Natychmiastowa informacja zwrotna | Standardowy proces przesyłania plików |
| Model bezpieczeństwa | Bardziej złożone (CORS, autoryzacja) | Proste |
| Wykorzystanie przepustowości | Niższy (przetworzony wstępnie na urządzeniu) | Wyższa (przesyłanie surowych obrazów) |
Jak wdrożyć skanowanie BarCode przy przesyłaniu plików?
Skanowanie plików przesyłanych to najczęstszy scenariusz wykorzystania BarCODE w aplikacjach internetowych ASP.NET. Ten wzorzec sprawdza się przy przetwarzaniu faktur, etykiet wysyłkowych lub dowolnych dokumentów z osadzonymi BARCODE-ami. Aby zwiększyć przepustowość, warto rozważyć wdrożenie asynchronicznego odczytu BarCode, co pozwoli na obsługę wielu przesyłek jednocześnie.
Tworzenie formularza przesyłania
Utwórz responsywny formularz HTML w widoku ASP.NET:
@* Razor view -- barcode upload form *@
<form method="post" enctype="multipart/form-data" id="barcodeForm">
<div class="form-group">
<label for="barcodeFile">Select Barcode Image:</label>
<input type="file" name="barcodeFile" id="barcodeFile"
accept="image/*,.pdf" class="form-control"
capture="environment" />
</div>
<button type="submit" class="btn btn-primary" id="scanBtn">
<span class="spinner-border spinner-border-sm d-none" role="status"></span>
Scan Barcode
</button>
</form>
<div id="results">
@ViewBag.BarcodeResult
</div>
@* Razor view -- barcode upload form *@
<form method="post" enctype="multipart/form-data" id="barcodeForm">
<div class="form-group">
<label for="barcodeFile">Select Barcode Image:</label>
<input type="file" name="barcodeFile" id="barcodeFile"
accept="image/*,.pdf" class="form-control"
capture="environment" />
</div>
<button type="submit" class="btn btn-primary" id="scanBtn">
<span class="spinner-border spinner-border-sm d-none" role="status"></span>
Scan Barcode
</button>
</form>
<div id="results">
@ViewBag.BarcodeResult
</div>
@* Razor view -- barcode upload form *@
<form method="post" enctype="multipart/form-data" id="barcodeForm">
<div class="form-group">
<label for="barcodeFile">Select Barcode Image:</label>
<input type="file" name="barcodeFile" id="barcodeFile"
accept="image/*,.pdf" class="form-control"
capture="environment" />
</div>
<button type="submit" class="btn btn-primary" id="scanBtn">
<span class="spinner-border spinner-border-sm d-none" role="status"></span>
Scan Barcode
</button>
</form>
<div id="results">
@ViewBag.BarcodeResult
</div>
Atrybut capture="environment" aktywuje tylny aparat w urządzeniach mobilnych, zapewniając użytkownikom wrażenia podobne do korzystania z natywnego aparatu bez użycia JavaScript.
Wdrażanie bezpiecznego przetwarzania zaplecza
Akcja kontrolera obsługuje walidację plików, przetwarzanie strumienia pamięci oraz formatowanie wyników:
[HttpPost]
[ValidateAntiForgeryToken]
[RequestSizeLimit(10_000_000)] // 10MB limit
public async Task<IActionResult> ScanBarcode(IFormFile barcodeFile)
{
var allowedExtensions = new[] { ".jpg", ".jpeg", ".png", ".gif",
".tiff", ".bmp", ".pdf" };
var extension = Path.GetExtension(barcodeFile.FileName).ToLowerInvariant();
if (!allowedExtensions.Contains(extension))
{
ModelState.AddModelError("", "Invalid file type");
return View();
}
if (barcodeFile != null && barcodeFile.Length > 0)
{
using var stream = new MemoryStream();
await barcodeFile.CopyToAsync(stream);
stream.Position = 0;
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
ExpectBarcodeTypes = BarcodeEncoding.AllOneDimensional |
BarcodeEncoding.QRCode |
BarcodeEncoding.DataMatrix,
ImageFilters = new ImageFilterCollection
{
new SharpenFilter(),
new ContrastFilter()
}
};
var results = BarcodeReader.Read(stream, options);
ViewBag.BarcodeResult = results.Any()
? string.Join("<br/>", results.Select(r => $"<strong>{r.BarcodeType}:</strong> {r.Text}"))
: "No barcodes found in the image.";
}
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
[RequestSizeLimit(10_000_000)] // 10MB limit
public async Task<IActionResult> ScanBarcode(IFormFile barcodeFile)
{
var allowedExtensions = new[] { ".jpg", ".jpeg", ".png", ".gif",
".tiff", ".bmp", ".pdf" };
var extension = Path.GetExtension(barcodeFile.FileName).ToLowerInvariant();
if (!allowedExtensions.Contains(extension))
{
ModelState.AddModelError("", "Invalid file type");
return View();
}
if (barcodeFile != null && barcodeFile.Length > 0)
{
using var stream = new MemoryStream();
await barcodeFile.CopyToAsync(stream);
stream.Position = 0;
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
ExpectBarcodeTypes = BarcodeEncoding.AllOneDimensional |
BarcodeEncoding.QRCode |
BarcodeEncoding.DataMatrix,
ImageFilters = new ImageFilterCollection
{
new SharpenFilter(),
new ContrastFilter()
}
};
var results = BarcodeReader.Read(stream, options);
ViewBag.BarcodeResult = results.Any()
? string.Join("<br/>", results.Select(r => $"<strong>{r.BarcodeType}:</strong> {r.Text}"))
: "No barcodes found in the image.";
}
return View();
}
Imports Microsoft.AspNetCore.Mvc
Imports Microsoft.AspNetCore.Http
Imports System.IO
Imports System.Threading.Tasks
Imports ZXing
<HttpPost>
<ValidateAntiForgeryToken>
<RequestSizeLimit(10_000_000)> ' 10MB limit
Public Async Function ScanBarcode(barcodeFile As IFormFile) As Task(Of IActionResult)
Dim allowedExtensions As String() = {".jpg", ".jpeg", ".png", ".gif", ".tiff", ".bmp", ".pdf"}
Dim extension As String = Path.GetExtension(barcodeFile.FileName).ToLowerInvariant()
If Not allowedExtensions.Contains(extension) Then
ModelState.AddModelError("", "Invalid file type")
Return View()
End If
If barcodeFile IsNot Nothing AndAlso barcodeFile.Length > 0 Then
Using stream As New MemoryStream()
Await barcodeFile.CopyToAsync(stream)
stream.Position = 0
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True,
.ExpectBarcodeTypes = BarcodeEncoding.AllOneDimensional Or
BarcodeEncoding.QRCode Or
BarcodeEncoding.DataMatrix,
.ImageFilters = New ImageFilterCollection From {
New SharpenFilter(),
New ContrastFilter()
}
}
Dim results = BarcodeReader.Read(stream, options)
ViewBag.BarcodeResult = If(results.Any(),
String.Join("<br/>", results.Select(Function(r) $"<strong>{r.BarcodeType}:</strong> {r.Text}")),
"No barcodes found in the image.")
End Using
End If
Return View()
End Function
Ta implementacja sprawdza typ pliku przed przetworzeniem, odczytuje BARCODES ze strumienia pamięci i zwraca wszystkie wykryte wyniki. IronBarcode przetwarza różne formaty obrazów, w tym wielostronicowe pliki TIFF, GIF i dokumenty PDF, eliminując konieczność stosowania kodu obsługującego konkretne formaty.
Jak wygląda zeskanowany tekst źródłowy i docelowy

Powyższy przykład przedstawia standardowy BarCode Code 128 — format powszechnie stosowany w aplikacjach do wysyłki i zarządzania zapasami. Po skanowaniu ekran wyników potwierdza zdekodowaną wartość wraz z metadanymi dotyczącymi pewności:

IronBarcode zwraca typ kodu kreskowego, zdekodowaną wartość, wynik pewności oraz dane dotyczące położenia dla każdego kodu kreskowego wykrytego na przesłanym obrazie.
Jak zbudować interfejs API REST do skanowania BarCodeów?
Nowoczesne aplikacje ASP.NET często udostępniają funkcje skanowania kodów kreskowych za pośrednictwem interfejsów API REST, umożliwiając integrację z aplikacjami mobilnymi, aplikacjami jednostronicowymi lub usługami stron trzecich. Ten wzorzec obsługuje przechwytywanie obrazu z kamery po stronie klienta z przetwarzaniem po stronie serwera.
Kwestie bezpieczeństwa związane z interfejsami API BarCode
Przed napisaniem kontrolera zaplanuj warstwę bezpieczeństwa. Dane BarCode mogą zawierać dowolną treść, dlatego należy zawsze weryfikować wprowadzane dane. Aby zapewnić pełną ochronę, należy przestrzegać wytycznych dotyczących bezpieczeństwa IronBarcode:
- Sprawdzanie poprawności danych wejściowych: Oczyszczanie treści BarCode przed ich zapisaniem lub wykonaniem operacji na nich
- Ograniczanie przepustowości: Użyj wbudowanego oprogramowania pośredniczącego .NET Core do ograniczania przepustowości, aby zapobiec nadużyciom API
- Uwierzytelnianie: Zabezpiecz punkty końcowe za pomocą tokenów JWT lub kluczy API
- Wymóg stosowania protokołu HTTPS: Cały ruch API związanego z kodami kreskowymi musi odbywać się za pośrednictwem protokołu TLS
- Polityka CORS: Ogranicz, które źródła mogą wywoływać Twój punkt końcowy skanowania
- Zarządzanie kluczami licencyjnymi: Prawidłowe stosowanie kluczy licencyjnych i konfigurowanie ich w pliku web.config dla środowiska produkcyjnego
Tworzenie kontrolera API produkcyjnego
[ApiController]
[Route("api/[controller]")]
public class BarcodeController : ControllerBase
{
private readonly ILogger<BarcodeController> _logger;
private readonly IMemoryCache _cache;
public BarcodeController(ILogger<BarcodeController> logger, IMemoryCache cache)
{
_logger = logger;
_cache = cache;
}
[HttpPost("scan")]
[ProducesResponseType(typeof(BarcodeResponse), 200)]
[ProducesResponseType(typeof(ErrorResponse), 400)]
public async Task<IActionResult> ScanBarcode([FromBody] BarcodeRequest request)
{
try
{
if (string.IsNullOrEmpty(request.ImageBase64))
return BadRequest(new ErrorResponse { Error = "Image data is required" });
var cacheKey = $"barcode_{request.ImageBase64.GetHashCode()}";
if (_cache.TryGetValue(cacheKey, out BarcodeResponse cachedResult))
return Ok(cachedResult);
byte[] imageBytes = Convert.FromBase64String(request.ImageBase64);
if (imageBytes.Length > 10 * 1024 * 1024)
return BadRequest(new ErrorResponse { Error = "Image size exceeds 10MB limit" });
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Faster,
ExpectMultipleBarcodes = request.ExpectMultiple ?? false,
UseConfidenceThreshold = true,
ConfidenceThreshold = 0.8
};
var results = await Task.Run(() => BarcodeReader.Read(imageBytes, options));
var response = new BarcodeResponse
{
Success = true,
Barcodes = results.Select(r => new BarcodeData
{
Type = r.BarcodeType.ToString(),
Value = r.Text,
Confidence = r.Confidence,
Position = new BarcodePosition
{
X = r.Points.Select(p => p.X).Min(),
Y = r.Points.Select(p => p.Y).Min(),
Width = r.Width,
Height = r.Height
}
}).ToList()
};
_cache.Set(cacheKey, response, TimeSpan.FromMinutes(5));
return Ok(response);
}
catch (FormatException)
{
return BadRequest(new ErrorResponse { Error = "Invalid base64 image data" });
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing barcode scan");
return StatusCode(500, new ErrorResponse { Error = "Internal server error" });
}
}
}
public record BarcodeRequest(string ImageBase64, bool? ExpectMultiple);
public record BarcodeResponse
{
public bool Success { get; init; }
public List<BarcodeData> Barcodes { get; init; } = new();
}
public record BarcodeData
{
public string Type { get; init; }
public string Value { get; init; }
public double Confidence { get; init; }
public BarcodePosition Position { get; init; }
}
public record BarcodePosition(int X, int Y, int Width, int Height);
public record ErrorResponse
{
public bool Success => false;
public string Error { get; init; }
}
[ApiController]
[Route("api/[controller]")]
public class BarcodeController : ControllerBase
{
private readonly ILogger<BarcodeController> _logger;
private readonly IMemoryCache _cache;
public BarcodeController(ILogger<BarcodeController> logger, IMemoryCache cache)
{
_logger = logger;
_cache = cache;
}
[HttpPost("scan")]
[ProducesResponseType(typeof(BarcodeResponse), 200)]
[ProducesResponseType(typeof(ErrorResponse), 400)]
public async Task<IActionResult> ScanBarcode([FromBody] BarcodeRequest request)
{
try
{
if (string.IsNullOrEmpty(request.ImageBase64))
return BadRequest(new ErrorResponse { Error = "Image data is required" });
var cacheKey = $"barcode_{request.ImageBase64.GetHashCode()}";
if (_cache.TryGetValue(cacheKey, out BarcodeResponse cachedResult))
return Ok(cachedResult);
byte[] imageBytes = Convert.FromBase64String(request.ImageBase64);
if (imageBytes.Length > 10 * 1024 * 1024)
return BadRequest(new ErrorResponse { Error = "Image size exceeds 10MB limit" });
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Faster,
ExpectMultipleBarcodes = request.ExpectMultiple ?? false,
UseConfidenceThreshold = true,
ConfidenceThreshold = 0.8
};
var results = await Task.Run(() => BarcodeReader.Read(imageBytes, options));
var response = new BarcodeResponse
{
Success = true,
Barcodes = results.Select(r => new BarcodeData
{
Type = r.BarcodeType.ToString(),
Value = r.Text,
Confidence = r.Confidence,
Position = new BarcodePosition
{
X = r.Points.Select(p => p.X).Min(),
Y = r.Points.Select(p => p.Y).Min(),
Width = r.Width,
Height = r.Height
}
}).ToList()
};
_cache.Set(cacheKey, response, TimeSpan.FromMinutes(5));
return Ok(response);
}
catch (FormatException)
{
return BadRequest(new ErrorResponse { Error = "Invalid base64 image data" });
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing barcode scan");
return StatusCode(500, new ErrorResponse { Error = "Internal server error" });
}
}
}
public record BarcodeRequest(string ImageBase64, bool? ExpectMultiple);
public record BarcodeResponse
{
public bool Success { get; init; }
public List<BarcodeData> Barcodes { get; init; } = new();
}
public record BarcodeData
{
public string Type { get; init; }
public string Value { get; init; }
public double Confidence { get; init; }
public BarcodePosition Position { get; init; }
}
public record BarcodePosition(int X, int Y, int Width, int Height);
public record ErrorResponse
{
public bool Success => false;
public string Error { get; init; }
}
Imports System
Imports Microsoft.AspNetCore.Mvc
Imports Microsoft.Extensions.Logging
Imports Microsoft.Extensions.Caching.Memory
Imports System.Threading.Tasks
<ApiController>
<Route("api/[controller]")>
Public Class BarcodeController
Inherits ControllerBase
Private ReadOnly _logger As ILogger(Of BarcodeController)
Private ReadOnly _cache As IMemoryCache
Public Sub New(logger As ILogger(Of BarcodeController), cache As IMemoryCache)
_logger = logger
_cache = cache
End Sub
<HttpPost("scan")>
<ProducesResponseType(GetType(BarcodeResponse), 200)>
<ProducesResponseType(GetType(ErrorResponse), 400)>
Public Async Function ScanBarcode(<FromBody> request As BarcodeRequest) As Task(Of IActionResult)
Try
If String.IsNullOrEmpty(request.ImageBase64) Then
Return BadRequest(New ErrorResponse With {.Error = "Image data is required"})
End If
Dim cacheKey = $"barcode_{request.ImageBase64.GetHashCode()}"
Dim cachedResult As BarcodeResponse = Nothing
If _cache.TryGetValue(cacheKey, cachedResult) Then
Return Ok(cachedResult)
End If
Dim imageBytes As Byte() = Convert.FromBase64String(request.ImageBase64)
If imageBytes.Length > 10 * 1024 * 1024 Then
Return BadRequest(New ErrorResponse With {.Error = "Image size exceeds 10MB limit"})
End If
Dim options = New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Faster,
.ExpectMultipleBarcodes = request.ExpectMultiple.GetValueOrDefault(False),
.UseConfidenceThreshold = True,
.ConfidenceThreshold = 0.8
}
Dim results = Await Task.Run(Function() BarcodeReader.Read(imageBytes, options))
Dim response = New BarcodeResponse With {
.Success = True,
.Barcodes = results.Select(Function(r) New BarcodeData With {
.Type = r.BarcodeType.ToString(),
.Value = r.Text,
.Confidence = r.Confidence,
.Position = New BarcodePosition With {
.X = r.Points.Select(Function(p) p.X).Min(),
.Y = r.Points.Select(Function(p) p.Y).Min(),
.Width = r.Width,
.Height = r.Height
}
}).ToList()
}
_cache.Set(cacheKey, response, TimeSpan.FromMinutes(5))
Return Ok(response)
Catch ex As FormatException
Return BadRequest(New ErrorResponse With {.Error = "Invalid base64 image data"})
Catch ex As Exception
_logger.LogError(ex, "Error processing barcode scan")
Return StatusCode(500, New ErrorResponse With {.Error = "Internal server error"})
End Try
End Function
End Class
Public Class BarcodeRequest
Public Property ImageBase64 As String
Public Property ExpectMultiple As Boolean?
End Class
Public Class BarcodeResponse
Public Property Success As Boolean
Public Property Barcodes As List(Of BarcodeData) = New List(Of BarcodeData)()
End Class
Public Class BarcodeData
Public Property Type As String
Public Property Value As String
Public Property Confidence As Double
Public Property Position As BarcodePosition
End Class
Public Class BarcodePosition
Public Property X As Integer
Public Property Y As Integer
Public Property Width As Integer
Public Property Height As Integer
End Class
Public Class ErrorResponse
Public ReadOnly Property Success As Boolean
Get
Return False
End Get
End Property
Public Property Error As String
End Class
Ten punkt końcowy akceptuje obrazy zakodowane w formacie base64 — standardowym formacie przesyłania obrazów przez HTTP. Odpowiedź zawiera typ BARCODE, zdekodowaną wartość, wynik pewności oraz pozycję. W przypadku dużych ilości danych warto zapoznać się z opcjami przetwarzania partii BARCODE-ów oraz optymalizacji szybkości odczytu.
W jaki sposób API obsługuje wiele BarCodes?

IronBarcode przetwarza wiele kodów kreskowych w jednym obrazie za pomocą jednego wywołania, zwracając tablicę wyników. Każdy wpis w odpowiedzi zawiera dane o położeniu, dzięki czemu aplikacja kliencka może podświetlić wykryte BARCODE na ekranie.

Strukturalna odpowiedź JSON zapewnia aplikacjom klienckim wszystko, co jest potrzebne do przetwarzania i wyświetlania wyników skanowania BARCODE bez konieczności dodatkowego wyszukiwania.
Jak radzisz sobie z trudnymi obrazami BarCode?
W praktyce skanowanie kodów kreskowych często wiąże się z niedoskonałymi obrazami — zdjęciami wykonanymi pod kątem, przy słabym oświetleniu lub z częściowo uszkodzonymi kodami kreskowymi. IronBarcode radzi sobie z tymi scenariuszami dzięki zaawansowanym możliwościom przetwarzania obrazu i progom pewności opartym na uczeniu maszynowym.
Diagnozowanie typowych problemów związanych ze skanowaniem
Przed wprowadzeniem poprawek określ, do której kategorii należy dany problem. Większość błędów skanowania w środowisku produkcyjnym można podzielić na pięć grup: problemy z jakością obrazu (rozmycie, szumy, niska rozdzielczość), problemy geometryczne (obrót, przekrzywienie, zniekształcenie perspektywy), problemy związane z uszkodzeniami (podarte etykiety, rozmazany tusz), problemy środowiskowe (odblaski, cienie, nierównomierne oświetlenie) oraz fałszywie pozytywne wykrycie, w którym czytnik wykrywa BARCODE, który nie istnieje.
Znajomość kategorii pomaga dobrać odpowiednią kombinację filtrów i prędkość odczytu bez konieczności przeprowadzania zbędnego przetwarzania każdego obrazu. W przypadku większości scenariuszy aplikacji internetowych, rozpoczęcie od ReadingSpeed.Balanced i AutoRotate = true obejmuje większość przypadków. Przekaż sprawę do ExtremeDetail tylko wtedy, gdy pierwsze przejście nie przyniesie żadnych wyników.
Podejście wieloetapowe w poniższym kodzie realizuje tę wielopoziomową strategię. Szybki pierwszy przebieg szybko obsługuje typowe obrazy, utrzymując niskie opóźnienie średnie w typowych przypadkach. Szczegółowa druga faza przetwarzania jest uruchamiana tylko wtedy, gdy pierwsza faza zakończy się niepowodzeniem, co gwarantuje, że ponosisz dodatkowe koszty przetwarzania tylko wtedy, gdy jest to rzeczywiście konieczne. Ten wzorzec zapewnia responsywność punktu końcowego ASP.NET przy normalnym obciążeniu, a jednocześnie niezawodnie obsługuje trudne przypadki skrajne.
| Problem | Objaw | Rozwiązanie |
|---|---|---|
| Niewyraźny obraz | Niskie wyniki pewności, pominięte fragmenty | Zastosuj filtr SharpenFilter, zwiększ prędkość ExtremeDetail |
| Obrócony BarCode | BarCode nie został wykryty | Włącz AutoRotate = true |
| Uszkodzony BarCode | Częściowe odczyty, nieprawidłowe wartości | Włącz korektę błędów, użyj RemoveFalsePositive |
| Słaby kontrast | Wykrywanie niespójności | Zastosuj filtry ContrastFilter i BrightnessFilter |
| Zbyt wolne działanie | Duże opóźnienia podczas przesyłania plików | Użyj ReadingSpeed.Faster, włącz wielowątkowość |
Wdrażanie wieloprzebiegówego przetwarzania obrazów
W przypadku trudnych obrazów najlepsze wyniki daje podejście oparte na przetwarzaniu warstwowym, które nie obniża wydajności w przypadku łatwych obrazów:
public class AdvancedBarcodeProcessor
{
private readonly ILogger<AdvancedBarcodeProcessor> _logger;
public async Task<List<ScannedBarcode>> ProcessChallengingImage(Stream imageStream)
{
// First pass -- fast, minimal processing
var fastOptions = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
AutoRotate = false,
UseConfidenceThreshold = true,
ConfidenceThreshold = 0.85
};
var results = BarcodeReader.Read(imageStream, fastOptions);
if (!results.Any())
{
// Second pass -- aggressive image correction
imageStream.Position = 0;
var detailedOptions = new BarcodeReaderOptions
{
Speed = ReadingSpeed.ExtremeDetail,
ExpectMultipleBarcodes = true,
AutoRotate = true,
RemoveFalsePositive = true,
UseConfidenceThreshold = true,
ConfidenceThreshold = 0.6,
Multithreaded = true,
ExpectBarcodeTypes = BarcodeEncoding.All,
ImageFilters = new ImageFilterCollection
{
new SharpenFilter(2.5f),
new ContrastFilter(2.0f),
new BrightnessFilter(1.2f),
new InvertFilter()
}
};
results = BarcodeReader.Read(imageStream, detailedOptions);
_logger.LogInformation("Second pass detected {Count} barcodes", results.Count());
}
return results.Select(r => new ScannedBarcode
{
Value = r.Text,
BarcodeType = r.BarcodeType.ToString(),
Confidence = r.Confidence,
RotationAngle = r.RotationAngle,
PageNumber = r.PageNumber
}).ToList();
}
}
public record ScannedBarcode
{
public string Value { get; init; }
public string BarcodeType { get; init; }
public double Confidence { get; init; }
public float RotationAngle { get; init; }
public int PageNumber { get; init; }
}
public class AdvancedBarcodeProcessor
{
private readonly ILogger<AdvancedBarcodeProcessor> _logger;
public async Task<List<ScannedBarcode>> ProcessChallengingImage(Stream imageStream)
{
// First pass -- fast, minimal processing
var fastOptions = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
AutoRotate = false,
UseConfidenceThreshold = true,
ConfidenceThreshold = 0.85
};
var results = BarcodeReader.Read(imageStream, fastOptions);
if (!results.Any())
{
// Second pass -- aggressive image correction
imageStream.Position = 0;
var detailedOptions = new BarcodeReaderOptions
{
Speed = ReadingSpeed.ExtremeDetail,
ExpectMultipleBarcodes = true,
AutoRotate = true,
RemoveFalsePositive = true,
UseConfidenceThreshold = true,
ConfidenceThreshold = 0.6,
Multithreaded = true,
ExpectBarcodeTypes = BarcodeEncoding.All,
ImageFilters = new ImageFilterCollection
{
new SharpenFilter(2.5f),
new ContrastFilter(2.0f),
new BrightnessFilter(1.2f),
new InvertFilter()
}
};
results = BarcodeReader.Read(imageStream, detailedOptions);
_logger.LogInformation("Second pass detected {Count} barcodes", results.Count());
}
return results.Select(r => new ScannedBarcode
{
Value = r.Text,
BarcodeType = r.BarcodeType.ToString(),
Confidence = r.Confidence,
RotationAngle = r.RotationAngle,
PageNumber = r.PageNumber
}).ToList();
}
}
public record ScannedBarcode
{
public string Value { get; init; }
public string BarcodeType { get; init; }
public double Confidence { get; init; }
public float RotationAngle { get; init; }
public int PageNumber { get; init; }
}
Imports System.IO
Imports System.Collections.Generic
Imports System.Linq
Imports System.Threading.Tasks
Public Class AdvancedBarcodeProcessor
Private ReadOnly _logger As ILogger(Of AdvancedBarcodeProcessor)
Public Async Function ProcessChallengingImage(imageStream As Stream) As Task(Of List(Of ScannedBarcode))
' First pass -- fast, minimal processing
Dim fastOptions As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True,
.AutoRotate = False,
.UseConfidenceThreshold = True,
.ConfidenceThreshold = 0.85
}
Dim results = BarcodeReader.Read(imageStream, fastOptions)
If Not results.Any() Then
' Second pass -- aggressive image correction
imageStream.Position = 0
Dim detailedOptions As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.ExtremeDetail,
.ExpectMultipleBarcodes = True,
.AutoRotate = True,
.RemoveFalsePositive = True,
.UseConfidenceThreshold = True,
.ConfidenceThreshold = 0.6,
.Multithreaded = True,
.ExpectBarcodeTypes = BarcodeEncoding.All,
.ImageFilters = New ImageFilterCollection From {
New SharpenFilter(2.5F),
New ContrastFilter(2.0F),
New BrightnessFilter(1.2F),
New InvertFilter()
}
}
results = BarcodeReader.Read(imageStream, detailedOptions)
_logger.LogInformation("Second pass detected {Count} barcodes", results.Count())
End If
Return results.Select(Function(r) New ScannedBarcode With {
.Value = r.Text,
.BarcodeType = r.BarcodeType.ToString(),
.Confidence = r.Confidence,
.RotationAngle = r.RotationAngle,
.PageNumber = r.PageNumber
}).ToList()
End Function
End Class
Public Class ScannedBarcode
Public Property Value As String
Public Property BarcodeType As String
Public Property Confidence As Double
Public Property RotationAngle As Single
Public Property PageNumber As Integer
End Class
Klasa BarcodeReaderOptions zapewnia precyzyjną kontrolę nad każdym aspektem skanowania. Ustawienie AutoRotate obsługuje obrazy przechwycone pod dowolnym kątem, a filtry obrazu poprawiają wyrazistość rozmytych lub mało kontrastowych BARCODE-ów. Szczegółowe informacje na temat konfiguracji można znaleźć w przykładzie ustawień czytnika BarCode oraz w ustawieniach czytnika dotyczących plików PDF.
Podczas pracy z plikami PDF warto rozważyć umieszczenie BARCODE-ów na plikach PDF lub tworzenie BARCODE-ów jako dokumentów PDF. W przypadku przetwarzania dużych ilości danych włączenie wielowątkowości za pomocą funkcji async i multithread znacznie poprawia przepustowość.
Dodanie strategii kompatybilności z przeglądarkami i strategii awaryjnych
Obsługa różnych przeglądarek wymaga stopniowego ulepszania. Nowoczesne przeglądarki na Androida oraz przeglądarki Chrome, Edge i Firefox na komputery stacjonarne obsługują interfejs API MediaDevices.getUserMedia() umożliwiający dostęp do aparatu. Safari na iOS obsługuje tę funkcję od wersji 11. Starsze przeglądarki Enterprise, tryby zgodności IE11 oraz niektóre zablokowane środowiska Enterprise mogą w ogóle nie obsługiwać dostępu do kamery, dlatego rezerwowa ścieżka przesyłania plików musi zawsze pozostawać funkcjonalna.
Zalecanym podejściem jest wykorzystanie wykrywania funkcji w czasie wykonywania zamiast sprawdzania agenta użytkownika, a następnie odpowiednie wyświetlanie lub ukrywanie interfejsu kamery. Zacznij od interfejsu obsługującego kamerę, a w razie potrzeby płynnie przejdź do przesyłania plików:
@* Razor view with progressive enhancement *@
<div class="barcode-scanner-container">
@* Camera capture -- hidden until JavaScript confirms support *@
<div id="cameraSection" class="d-none">
<video id="videoPreview" class="w-100" autoplay></video>
<button id="captureBtn" class="btn btn-primary mt-2">Capture and Scan</button>
</div>
@* File upload -- always available as fallback *@
<div id="uploadSection">
<form method="post" enctype="multipart/form-data"
asp-action="ScanBarcode" asp-controller="Barcode">
<div class="form-group">
<label>Upload Barcode Image:</label>
<input type="file" name="file" accept="image/*,.pdf"
class="form-control" required />
</div>
<button type="submit" class="btn btn-primary">Upload and Scan</button>
</form>
</div>
</div>
@* Razor view with progressive enhancement *@
<div class="barcode-scanner-container">
@* Camera capture -- hidden until JavaScript confirms support *@
<div id="cameraSection" class="d-none">
<video id="videoPreview" class="w-100" autoplay></video>
<button id="captureBtn" class="btn btn-primary mt-2">Capture and Scan</button>
</div>
@* File upload -- always available as fallback *@
<div id="uploadSection">
<form method="post" enctype="multipart/form-data"
asp-action="ScanBarcode" asp-controller="Barcode">
<div class="form-group">
<label>Upload Barcode Image:</label>
<input type="file" name="file" accept="image/*,.pdf"
class="form-control" required />
</div>
<button type="submit" class="btn btn-primary">Upload and Scan</button>
</form>
</div>
</div>
@* Razor view with progressive enhancement *@
<div class="barcode-scanner-container">
@* Camera capture -- hidden until JavaScript confirms support *@
<div id="cameraSection" class="d-none">
<video id="videoPreview" class="w-100" autoplay></video>
<button id="captureBtn" class="btn btn-primary mt-2">Capture and Scan</button>
</div>
@* File upload -- always available as fallback *@
<div id="uploadSection">
<form method="post" enctype="multipart/form-data"
asp-action="ScanBarcode" asp-controller="Barcode">
<div class="form-group">
<label>Upload Barcode Image:</label>
<input type="file" name="file" accept="image/*,.pdf"
class="form-control" required />
</div>
<button type="submit" class="btn btn-primary">Upload and Scan</button>
</form>
</div>
</div>
Integracja z Blazorem zapewnia obsługę nowoczesnych aplikacji internetowych przy minimalnej konfiguracji, jeśli preferujesz podejście oparte na komponentach. W przypadku rozwiązywania problemów związanych z wdrażaniem należy zapoznać się z przewodnikiem dotyczącym wyjątków kopiowania środowisk uruchomieniowych.
Jakie są Twoje kolejne kroki?
Skanowanie kodów kreskowych w ASP.NET jest proste dzięki IronBarcode. Wystarczy zainstalować jeden pakiet NuGet, wywołać BarcodeReader.Read() i uzyskać wiarygodne wyniki dekodowania w ponad 30 formatach — w tym trudnych, rzeczywistych obrazach, z którymi inne biblioteki mają problemy.
Aby dalej rozwijać się w tym zakresie, zapoznaj się z poniższymi zasobami:
- Samouczek dotyczący odczytu BarCodes — szczegółowy przewodnik dotyczący wszystkich scenariuszy skanowania
- Generowanie kodów kreskowych — programowe tworzenie kodów kreskowych i kodów QR
- Generator kodów QR — funkcje i stylizacja specyficzne dla kodów QR
- Korekcja obrazu — techniki poprawiające dokładność skanowania trudnych obrazów
- Asynchroniczność i wielowątkowość — skalowanie przetwarzania BarCode dla aplikacji o dużym natężeniu ruchu
- Kompatybilność międzyplatformowa — wdrażanie w systemach Windows, Linux, Docker, Azure i AWS
- Obsługiwane formaty BarCodes — pełna lista symboli, które można odczytać i zapisać
- Funkcje odporności na awarie — niezawodne działanie w niekorzystnych warunkach
- Dokumentacja API — kompletna dokumentacja wszystkich klas i opcji
- Opcje licencyjne — licencje SaaS, OEM i Enterprise do wdrożeń produkcyjnych
Zacznij od bezpłatnej licencji próbnej, aby przetestować IronBarcode w swojej aplikacji ASP.NET bez żadnych ograniczeń. Wersja próbna zapewnia pełny dostęp do wszystkich funkcji, w tym wykrywania wielu formatów, korekcji obrazów oraz wzorców REST API przedstawionych w tym przewodniku — dzięki czemu można ocenić wydajność na własnych obrazach przed zakupem licencji produkcyjnej. W przypadku aplikacji mobilnych .NET MAUI, które wymagają skanowania na urządzeniu, zapoznaj się z samouczkiem dotyczącym skanera BARCODE .NET MAUI, który rozszerza ten sam interfejs API na platformy iOS i Android.
Często Zadawane Pytania
Jakie jest główne zastosowanie skanowania BarCode w aplikacjach ASP.NET?
Skanowanie BarCode w aplikacjach ASP.NET służy przede wszystkim do usprawnienia systemów zarządzania zapasami, obsługi biletów podczas wydarzeń oraz digitalizacji dokumentów papierowych, co pozwala zwiększyć wydajność i ograniczyć liczbę błędów.
W jaki sposób IronBarcode ułatwia skanowanie kodów kreskowych w ASP.NET?
IronBarcode upraszcza proces skanowania kodów kreskowych w ASP.NET, dostarczając niezawodne i wydajne komponenty, które można łatwo zintegrować z aplikacjami internetowymi, umożliwiając programistom szybkie wdrażanie funkcji skanowania.
Jakie rodzaje kodów kreskowych można skanować za pomocą IronBarcode?
IronBarcode obsługuje skanowanie szerokiej gamy formatów kodów kreskowych, w tym tradycyjnych kodów liniowych i nowoczesnych kodów 2D, zapewniając kompatybilność z różnorodnymi aplikacjami.
Czy IronBarcode może obsługiwać skanowanie kodów kreskowych do przetwarzania dokumentów?
Tak, IronBarcode doskonale nadaje się do procesów przetwarzania dokumentów, gdzie może służyć do digitalizacji i porządkowania dokumentów papierowych poprzez skanowanie wbudowanych kodów kreskowych.
Czy IronBarcode nadaje się do systemów zarządzania zapasami?
IronBarcode to doskonały wybór dla systemów zarządzania zapasami, ponieważ umożliwia wydajne śledzenie produktów poprzez skanowanie kodów kreskowych, usprawniając w ten sposób operacje i minimalizując błędy.
W jaki sposób integracja IronBarcode usprawnia przetwarzanie biletów na wydarzenia?
Dzięki integracji z IronBarcode przetwarzanie biletów na wydarzenia staje się płynne, ponieważ umożliwia szybkie skanowanie kodów kreskowych biletów, ułatwiając szybkie i dokładne zarządzanie wejściami podczas wydarzeń.
Jakie są zalety korzystania z IronBarcode w projektach ASP.NET?
Wykorzystanie IronBarcode w projektach ASP.NET oferuje szereg korzyści, w tym łatwość integracji, obsługę wielu formatów kodów kreskowych oraz zwiększoną wydajność aplikacji, zapewniając w ten sposób solidne rozwiązanie dla potrzeb skanowania kodów kreskowych.
Czy wdrożenie IronBarcode wymaga rozległej wiedzy z zakresu programowania?
Nie, IronBarcode został zaprojektowany z myślą o programistach, co ułatwia wdrażanie funkcji skanowania kodów kreskowych w aplikacjach ASP.NET przy minimalnej wiedzy programistycznej.
Czy IronBarcode może być używany w mobilnych aplikacjach internetowych?
Tak, IronBarcode można zintegrować z mobilnymi aplikacjami internetowymi, co pozwala na skanowanie kodów kreskowych w dowolnym miejscu i zwiększa wszechstronność projektów ASP.NET.




