푸터 콘텐츠로 바로가기
IRONBARCODE 사용

ASP.NET 바코드 스캐너: IronBarcode 사용한 파일 업로드 및 REST API

ASP.NET에서 바코드 스캔은 IronBarcode 덕분에 간단해집니다: NuGet을 통해 설치하고, BarcodeReader.Read()을 호출하여 유형, 신뢰도, 위치 데이터와 함께 디코딩된 값을 한 단계로 얻을 수 있습니다. 복잡한 구성이 필요하지 않습니다.

바코드 스캔은 현대 웹 응용 프로그램에서 인벤토리 관리, 문서 처리 및 티켓 검증 워크플로를 지원하는 표준 요구사항입니다. GS1에 따르면, 바코드는 매일 전 세계적으로 60억 건 이상의 거래에서 사용되며, 이는 비즈니스 시스템에 있어 정확한 바코드 읽기가 얼마나 중요한지를 보여주는 수치입니다. ISO/IEC 15415 표준은 2D 바코드 심볼에 대한 품질 메트릭을 정의하고, ISO/IEC 15416 표준은 1D 선형 바코드를 다루며, 둘 다 IronBarcode가 기본적으로 지원합니다.

이 가이드에서는 IronBarcode를 사용하여 ASP.NET Core 응용 프로그램에 신뢰할 수 있는 바코드 스캔을 추가하는 방법을 설명하며, 설치, 파일 업로드 처리, REST API 통합 및 프로덕션 배포 패턴을 다룹니다. 마지막에는 Razor 페이지 파일 업로드 스캐너와 어떤 클라이언트로부터도 base64 인코딩 이미지를 수용할 수 있는 JSON API 엔드포인트에 대한 작동 가능한 코드를 갖게 될 것입니다.

ASP.NET 프로젝트에 IronBarcode를 설치하는 방법?

시작하는 데 몇 분밖에 걸리지 않습니다. 이 라이브러리는 ASP.NET Core와 전통적인 ASP.NET MVC 응용 프로그램 모두를 지원하여 다양한 프로젝트 유형에 적응할 수 있습니다. Enterprise 배포는 Azure, AWS Lambda, 및 Docker 컨테이너에서 동일하게 잘 작동합니다. 이 라이브러리의 기계 학습 기반 감지는 복잡한 이미지 보정을 자동으로 적용하여 까다로운 바코드 이미지를 처리할 수 있도록 하며, 이는 특히 가변적인 조명 조건에서 모바일 카메라로 촬영한 사진을 처리할 때 유용합니다.

NuGet 패키지 관리자를 통한 설치

Visual Studio에서 패키지 관리자 콘솔을 열고 다음을 실행하세요:

Install-Package BarCode
Install-Package BarCode
SHELL

.NET CLI를 사용하세요:

dotnet add package BarCode
dotnet add package BarCode
SHELL

또는 Visual Studio NuGet 패키지 관리자 UI에서 "BarCode"를 검색하고 설치를 클릭하세요. 패키지는 모든 종속성을 자동으로 관리합니다.

플랫폼별 배포를 위해 플랫폼별 NuGet 패키지를 사용하는 것을 고려하세요. 이는 귀하의 대상 환경에 최적화되어 있습니다. 라이브러리는 다양한 배포 시나리오에 맞게 표준 및 BarCode.Slim 패키지를 제공합니다. 설치 전 과정을 보려면 IronBarcode 설치 가이드를 참조하세요.

프로젝트 구성하기

설치 후, 필요한 using 구문을 C# 파일에 추가하세요:

using IronBarCode;
using IronBarCode;
$vbLabelText   $csharpLabel

이 임포트를 통해 IronBarcode의 완전한 바코드 읽기생성 기능에 액세스할 수 있습니다. 라이브러리는 QR 코드, Code 128, Code 39, Data Matrix, PDF417을 포함하여 30개 이상의 바코드 형식을 지원합니다. 사용 사례와의 호환성을 확인하려면 지원되는 바코드 형식의 전체 목록을 확인하세요.

설치 문제 해결을 위해 NuGet 패키지 문제 해결 가이드를 참조하거나 엔지니어링 요청을 제출하여 전문화된 지원을 받으세요.

올바른 아키텍처 패턴 선택하기

ASP.NET에서 바코드 스캐닝을 구현할 때 두 가지 기본 아키텍처 접근 방식이 있습니다. 이러한 패턴을 이해하면 각 사용 사례에 맞는 적절한 바코드 리더 설정을 선택할 수 있습니다:

// 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}");
}
$vbLabelText   $csharpLabel

서버 측 접근 방식은 이미지 처리에 대한 최대 제어권을 제공하며 모든 브라우저에서 일관되게 작동합니다. 서버가 모든 이미지를 처리하면 모든 스캔된 바코드는 애플리케이션 레이어를 통과하여 로그를 남기거나 데이터베이스에 대해 유효성을 검사하거나 하위 워크플로를 트리거하는 등 명확한 감사 추적을 얻을 수 있습니다. 이 패턴은 모든 스캔이 기록되어야 하는 의료, 물류, 제조와 같은 규제 산업에 특히 적합합니다.

클라이언트 측 카메라 캡처 통합의 경우, 최신 브라우저는 카메라 접근을 위한 MediaDevices API를 지원하며, 이는 IronBarcode의 서버 사이드 처리와 REST API를 통해 결합될 수 있습니다. 이 가이드의 후반부에서 자세히 다룹니다. 서버 사이드 처리를 선택하면 보안 모델도 간단해집니다: 민감한 처리 로직이 브라우저에 노출되지 않으며, 모든 검증은 애플리케이션 경계 뒤에서 이루어집니다.

클라이언트 측 vs. 서버 측 바코드 스캔의 장단점
측면 클라이언트 측 캡처 + 서버 처리 순수 서버 측 처리
~에 가장 적합함 카메라를 통한 실시간 스캔 일괄 처리, 파일 업로드
브라우저 지원 현대적인 브라우저만 모든 브라우저
사용자 경험 즉시 피드백 표준 업로드 흐름
보안 모델 더 복잡함 (CORS, 인증) 단순함
대역폭 사용 낮음(기기에서 사전 처리) 높음(원시 이미지 업로드)

파일 업로드 바코드 스캔을 어떻게 구현하나요?

파일 업로드 스캔은 ASP.NET 웹 애플리케이션에서 가장 일반적인 바코드 시나리오입니다. 이 패턴은 청구서, 배송 라벨 또는 바코드가 포함된 문서를 처리하는 데 적합합니다. 처리량을 개선하려면 비동기 바코드 읽기를 구현하여 동시에 여러 업로드를 처리하는 것을 고려하세요.

업로드 폼 구축하기

ASP.NET 뷰에 반응형 HTML 폼을 생성하세요:

@* 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>
$vbLabelText   $csharpLabel

capture="environment" 속성은 모바일 장치에서 후면 카메라를 활성화하여 사용자에게 JavaScript 없이 네이티브 카메라 같은 경험을 제공합니다.

보안 백엔드 처리 구현하기

컨트롤러 액션은 파일 유효성 검사, 메모리 스트림 처리, 결과 형식을 처리합니다:

[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();
}
$vbLabelText   $csharpLabel

이 구현은 파일 유형을 처리하기 전에 유효성을 검사하고, 메모리 스트림에서 바코드를 읽고, 감지된 모든 결과를 반환합니다. IronBarcode는 다양한 이미지 형식, 멀티페이지 TIFF 및 GIF, PDF 문서를 처리하여 형식별 처리 코드를 제거합니다.

스캔된 입력과 출력은 어떻게 보이나요

ASP.NET 바코드 리더 애플리케이션에서 정확한 스캔을 위해 기계가 읽을 수 있는 막대와 그 아래에 사람 읽을 수 있는 텍스트를 표시하여 'https://ironsoftware.com/csharp/barcode/' URL을 코드 128 바코드로 인코딩합니다

위의 예는 일반적인 배송 및 재고 응용 프로그램에서 사용하는 표준 Code 128 바코드를 보여줍니다. 스캔 후 결과 화면은 디코딩된 값과 함께 신뢰성 메타데이터를 확인합니다:

디코딩된 Code128 바코드 값과 신뢰도 메타데이터를 표시하는 파일 업로드 양식과 함께 성공적인 바코드 스캔 결과가 표시된 ASP.NET Core 웹 애플리케이션 인터페이스

IronBarcode는 업로드된 이미지에서 탐지된 각 바코드에 대해 바코드 유형, 디코딩된 값, 신뢰성 점수, 위치 데이터를 반환합니다.

바코드 스캐닝을 위한 REST API를 어떻게 구축합니까?

현대적인 ASP.NET 응용 프로그램은 종종 REST API를 통해 바코드 스캐닝 기능을 노출하여 모바일 앱, 단일 페이지 응용 프로그램 또는 타사 서비스와 통합을 허용합니다. 이 패턴은 서버 측 처리를 통해 클라이언트 측 카메라 캡처를 지원합니다.

바코드 API의 보안 고려사항

컨트롤러를 작성하기 전에 보안 레이어를 계획하십시오. 바코드 데이터에는 임의의 콘텐츠가 포함될 수 있으므로 항상 입력을 유효성 검증해야 합니다. IronBarcode 보안 지침을 따라 완벽한 보호를 구현하십시오:

  • 입력 유효성 검증: 바코드 콘텐츠를 저장하거나 사용하는 전에 소독하십시오
  • 속도 제한: API 남용을 방지하기 위해 ASP.NET Core의 내장 속도 제한 미들웨어를 사용하십시오
  • 인증: JWT 토큰 또는 API 키로 엔드포인트를 보호하십시오
  • HTTPS 강화: 모든 바코드 API 트래픽은 TLS를 통해 전송해야 합니다
  • CORS 정책: 스캐닝 엔드포인트를 호출할 수 있는 출처를 제한하십시오
  • 라이선스 키 관리: 올바르게 라이선스 키를 적용하십시오웹.config에 구성하십시오 라는 프로덕션

프로덕션 API 컨트롤러 구축하기

[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; }
}
$vbLabelText   $csharpLabel

이 엔드포인트는 HTTP를 통해 이미지를 전송하는 표준 형식인 base64로 인코딩된 이미지를 수락합니다. 응답에는 바코드 유형, 디코딩된 값, 신뢰성 점수 및 위치가 포함됩니다. 대량 처리 시나리오에서는 배치 바코드 처리읽기 속도 최적화 옵션을 검토하십시오.

API가 여러 바코드를 어떻게 처리합니까?

IronBarcode가 생산 환경에서 동시에 처리하는 QR 코드, Code128, DataMatrix 심볼로지를 보여주는 A, B, C로 표시된 세 가지 다른 바코드 형식

IronBarcode는 하나의 이미지 내에서 여러 바코드를 한 번의 호출로 처리하여 결과의 배열을 반환합니다. 응답의 각 항목에는 클라이언트 응용 프로그램이 화면에 탐지된 바코드를 강조 표시할 수 있도록 위치 데이터가 포함되어 있습니다.

타입 값, 신뢰도, 위치 좌표를 포함한 완전한 메타데이터가 포함된 세 개의 감지된 바코드 배열을 포함한 성공적인 JSON API 응답을 보여주는 브라우저 개발자 도구 네트워크 탭

구조화된 JSON 응답은 클라이언트 애플리케이션이 추가 조회 없이 바코드 결과를 처리하고 표시하는 데 필요한 모든 것을 제공합니다.

어려운 바코드 이미지를 어떻게 처리합니까?

실제 세계의 바코드 스캐닝은 종종 불완전한 이미지를 포함합니다. 각도에서 찍힌 사진, 조명이 나쁜 경우, 일부 손상된 바코드 등이 그렇습니다. IronBarcode는 고급 이미지 처리 기능머신 러닝 신뢰성 임계값을 통해 이러한 시나리오를 처리합니다.

일반적인 스캐닝 문제 진단

수정을 적용하기 전에 문제가 어떤 범주에 속하는지 식별하십시오. 프로덕션에서 스캐닝 실패의 대부분은 다섯 가지 그룹 중 하나에 속합니다: 이미지 품질 문제(흐림, 노이즈, 해상도 저하), 기하학적 문제(회전, 기울기, 원근 왜곡), 손상 문제(찢어진 라벨, 얼룩진 잉크), 환경 문제(눈부심, 그림자, 조명 불일치), 그리고 존재하지 않는 바코드를 읽는 잘못된 긍정 탐지.

범주를 알면 불필요한 처리를 피하면서 올바른 필터 조합과 읽기 속도를 선택하는 데 도움이 됩니다. 대부분의 웹 애플리케이션 시나리오에서는 ReadingSpeed.BalancedAutoRotate = true로 시작하면 대부분의 케이스를 커버할 수 있습니다. 첫 번째 패스에서 결과가 없을 때만 ExtremeDetail로 단계적으로 상승합니다.

아래 코드의 여러 패스 접근법은 이 계층 전략을 구현합니다. 빠른 첫 번째 패스는 전형적인 이미지를 빠르게 처리하여 일반적인 케이스에서 중간 지연 시간을 낮게 유지합니다. 첫 번째 패스가 실패할 때만 세부적인 두 번째 패스를 트리거하여 실제로 필요할 때만 추가 처리 비용을 지불하도록 보장합니다. 이 패턴은 ASP.NET 엔드포인트를 정상적인 부하 하에서 응답 속도를 유지하면서도 어려운 극단적인 경우를 신뢰성 있게 처리합니다.

일반적인 바코드 스캐닝 문제 및 해결책
문제 증상 해결책
흐릿한 이미지 낮은 신뢰성 점수, 놓친 읽기 `SharpenFilter` 적용, `ExtremeDetail` 속도 증가
회전된 바코드 바코드가 전혀 감지되지 않음 `AutoRotate = true` 활성화
손상된 바코드 부분 읽기, 잘못된 값 오류 수정을 활성화하고, `RemoveFalsePositive`를 사용하십시오.
대비가 좋지 않음 감지가 일관되지 않음 `ContrastFilter` 및 `BrightnessFilter`를 적용하십시오.
성능이 너무 느림 업로드 시 지연 시간이 높음 `ReadingSpeed.Faster`를 사용하고 다중 스레드를 활성화하십시오.

다중 패스 이미지 처리 구현하기

복잡한 이미지에는 계층적 처리 접근 방식이 성능을 저하하지 않으면서 최상의 결과를 제공합니다:

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; }
}
$vbLabelText   $csharpLabel

BarcodeReaderOptions 클래스는 스캔의 모든 측면에 대한 세부 제어를 제공합니다. AutoRotate 설정은 어떤 각도로 캡처된 이미지도 처리할 수 있으며, 이미지 필터는 흐리거나 대비가 낮은 바코드의 선명도를 향상시킵니다. 자세한 설정은 바코드 리더 설정 예제PDF 전용 리더 설정을 참조하십시오.

PDF를 다룰 때, PDF에 바코드 찍기 또는 PDF 문서로 바코드 생성하기를 고려하십시오. 대량 처리의 경우, 비동기 및 멀티스레드 기능을 활성화하여 처리량을 크게 향상시킬 수 있습니다.

브라우저 호환성과 대체 전략 추가하기

다양한 브라우저를 지원하기 위해서는 점진적 향상이 필요합니다. 안드로이드와 데스크톱 Chrome, Edge, Firefox의 최신 브라우저는 카메라 접근을 위한 MediaDevices.getUserMedia() API를 지원합니다. iOS의 Safari는 버전 11부터 이를 지원합니다. 구형 Enterprise 브라우저, IE11 호환 모드 및 특정 엄격한 기업 환경에서는 카메라 접근이 아예 지원되지 않을 수 있으므로, 대체 파일 업로드 경로가 항상 작동해야 합니다.

추천 접근 방식은 실행 시 기능 감지를 사용하여 사용자를 탐지하기보다는, 카메라 인터페이스를 그에 따라 표시하거나 숨기는 것입니다. 카메라가 가능한 인터페이스로 시작하고 파일 업로드로 우아하게 대체하십시오:

@* 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>
$vbLabelText   $csharpLabel

Blazor 통합은 구성 없이 최소의 웹 애플리케이션 지원을 제공합니다. 배포 문제 해결을 위해 런타임 복사 예외 가이드를 참조하십시오.

다음 단계는 무엇입니까?

ASP.NET에서 IronBarcode를 사용한 바코드 스캔은 간단합니다. NuGet 패키지를 설치하고, BarcodeReader.Read()을 호출하면, 다른 라이브러리들이 어려워하는 현실 세계의 복잡한 이미지를 포함하여 30개 이상의 형식에서 신뢰할 수 있는 디코딩 결과를 얻을 수 있습니다.

이 기본을 기반으로 계속 구축하려면 다음 리소스를 탐색하십시오:

무료 체험 라이선스로 ASP.NET 애플리케이션에서 IronBarcode를 테스트하십시오. 체험판은 다중 형식 감지, 이미지 수정 및 REST API 패턴을 포함한 모든 기능에 대한 전체 액세스를 포함하여, 프로덕션 라이선스에 전념하기 전에 자신의 이미지에 대한 성능을 평가할 수 있습니다. .NET MAUI 모바일 앱의 경우, 장치 내 스캐닝이 필요하다면 .NET MAUI 바코드 스캐너 튜토리얼을 확인하십시오. 이 튜토리얼은 같은 API를 iOS 및 안드로이드 타겟에 확장합니다.

자주 묻는 질문

ASP.NET 애플리케이션에서 바코드 스캐닝의 주요 용도는 무엇입니까?

ASP.NET 애플리케이션에서 바코드 스캐닝은 주로 재고 관리 시스템을 개선하고, 이벤트 티켓을 처리하고, 종이 문서를 디지털화하는 데 사용되어 효율성을 높이고 오류를 줄입니다.

IronBarcode ASP.NET 에서 바코드 스캔을 어떻게 지원합니까?

IronBarcode ASP.NET 에서 바코드 스캔 프로세스를 간소화합니다. 웹 애플리케이션에 쉽게 통합할 수 있는 안정적이고 효율적인 구성 요소를 제공하여 개발자가 스캔 기능을 신속하게 구현할 수 있도록 지원합니다.

IronBarcode 로 스캔할 수 있는 바코드 종류는 무엇인가요?

IronBarcode 기존의 선형 바코드와 최신 2D 바코드를 포함한 다양한 바코드 형식을 스캔할 수 있도록 지원하여 다양한 애플리케이션과의 호환성을 보장합니다.

IronBarcode 문서 처리를 위한 바코드 스캔 기능을 지원합니까?

네, IronBarcode 문서 처리 워크플로에 매우 적합하며, 내장된 바코드를 스캔하여 종이 문서를 디지털화하고 정리하는 데 사용할 수 있습니다.

IronBarcode 재고 관리 시스템에 적합한가요?

IronBarcode 바코드를 스캔하여 제품을 효율적으로 추적할 수 있으므로 재고 관리 시스템에 탁월한 선택이며, 운영을 간소화하고 오류를 최소화합니다.

IronBarcode 통합하면 이벤트 티켓 처리 과정이 어떻게 개선되나요?

IronBarcode 통합하면 티켓 바코드를 빠르게 스캔할 수 있어 이벤트 티켓 처리 과정이 원활해지고, 행사장에서 신속하고 정확한 입장 관리가 가능해집니다.

ASP.NET 프로젝트에서 IronBarcode 사용하는 장점은 무엇인가요?

ASP.NET 프로젝트에서 IronBarcode 사용하면 손쉬운 통합, 다양한 바코드 형식 지원, 향상된 애플리케이션 성능 등 여러 가지 이점을 누릴 수 있으므로 바코드 스캔 요구 사항에 대한 강력한 솔루션을 제공합니다.

IronBarcode 구현하려면 광범위한 코딩 지식이 필요합니까?

아니요, IronBarcode 는 개발자 친화적으로 설계되어 있어 코딩 지식이 최소한이라도 있으면 ASP.NET 애플리케이션에 바코드 스캔 기능을 쉽게 구현할 수 있습니다.

IronBarcode 모바일 웹 애플리케이션에 사용할 수 있나요?

네, IronBarcode 모바일 웹 애플리케이션에 통합할 수 있어 이동 중에도 바코드를 스캔할 수 있으며 ASP.NET 프로젝트의 활용도를 높여줍니다.

커티스 차우
기술 문서 작성자

커티스 차우는 칼턴 대학교에서 컴퓨터 과학 학사 학위를 취득했으며, Node.js, TypeScript, JavaScript, React를 전문으로 하는 프론트엔드 개발자입니다. 직관적이고 미적으로 뛰어난 사용자 인터페이스를 만드는 데 열정을 가진 그는 최신 프레임워크를 활용하고, 잘 구성되고 시각적으로 매력적인 매뉴얼을 제작하는 것을 즐깁니다.

커티스는 개발 분야 외에도 사물 인터넷(IoT)에 깊은 관심을 가지고 있으며, 하드웨어와 소프트웨어를 통합하는 혁신적인 방법을 연구합니다. 여가 시간에는 게임을 즐기거나 디스코드 봇을 만들면서 기술에 대한 애정과 창의성을 결합합니다.

Iron Support Team

We're online 24 hours, 5 days a week.
Chat
Email
Call Me