IronBarcode 사용하여 .NET 용 C#에서 바코드 이미지를 생성하는 방법
Dynamsoft Barcode Reader에서 IronBarcode로 마이그레이션
Dynamsoft Barcode Reader에서 IronBarcode로 마이그레이션하는 대부분의 개발자는 두 그룹 중 하나에 속합니다: 명성 때문에 Dynamsoft를 선택했지만, 카메라 중심 API가 문서 처리 사용 사례와 일치하지 않는 것을 발견한 사람들; 그리고 라이선스 서버 의존성이 생산 사고를 발생시킨 에어갭 또는 Docker 환경에서 실행 중인 사람들.
첫 번째 그룹에 속하는 경우, 마이그레이션을 통해 외부 PDF 렌더링 라이브러리, 페이지별 렌더링 루프 및 오류 코드 라이선스 패턴이 제거됩니다. 만약 당신이 두 번째 그룹에 속한다면, 마이그레이션은 InitLicense 네트워크 호출, 오프라인 라이선스 콘텐츠 번들 및 갱신 주기, 그리고 Docker 또는 VPC 구성에서 외부 네트워크 정책을 제거합니다. 어떤 방식이든 이번 마이그레이션을 통해 코드베이스가 더 짧아집니다.
이 가이드는 당신이 잃는 것에 대해 솔직합니다: 애플리케이션이 실시간 카메라 프레임을 처리한다면, Dynamsoft의 캡쳐 비전 파이프 라인은 해당 워크로드에 맞춰 조정되었으며, IronBarcode는 적합한 대체물이 아닙니다. 이 마이그레이션 가이드는 서버 측 파일 처리, 문서 워크플로 및 라이선스 서버 액세스에 문제가 있는 환경을 위한 것입니다.
1단계: NuGet 패키지 교체
dotnet remove package Dynamsoft.DotNet.BarcodeReader.Bundle
dotnet add package BarCode
dotnet remove package Dynamsoft.DotNet.BarcodeReader.Bundle
dotnet add package BarCode
프로젝트에 Dynamsoft 전용 PDF 렌더링 라이브러리(가장 일반적인 예는 PdfiumViewer)가 추가된 경우, 해당 라이브러리도 제거할 수 있습니다.
# Remove if added only for Dynamsoft PDF support
dotnet remove package PdfiumViewer
dotnet remove package PdfiumViewer.Native.x86_64.v8-xfa
# Remove if added only for Dynamsoft PDF support
dotnet remove package PdfiumViewer
dotnet remove package PdfiumViewer.Native.x86_64.v8-xfa
2단계: 라이선스 초기화 교체
가장 즉각적인 단순화가 이루어지는 곳이 바로 여기입니다. Dynamsoft 패턴은 매 시작 시마다 오류 코드 검사 및 예외 처리를 요구합니다.
이전 — 다이나모프트:
using Dynamsoft.License;
using Dynamsoft.Core;
// Must run before any barcode operations
int errorCode = LicenseManager.InitLicense("YOUR-DYNAMSOFT-KEY", out string errorMsg);
if (errorCode != (int)EnumErrorCode.EC_OK)
throw new InvalidOperationException($"License validation failed [{errorCode}]: {errorMsg}");
using Dynamsoft.License;
using Dynamsoft.Core;
// Must run before any barcode operations
int errorCode = LicenseManager.InitLicense("YOUR-DYNAMSOFT-KEY", out string errorMsg);
if (errorCode != (int)EnumErrorCode.EC_OK)
throw new InvalidOperationException($"License validation failed [{errorCode}]: {errorMsg}");
Imports Dynamsoft.License
Imports Dynamsoft.Core
' Must run before any barcode operations
Dim errorCode As Integer = LicenseManager.InitLicense("YOUR-DYNAMSOFT-KEY", errorMsg)
If errorCode <> CType(EnumErrorCode.EC_OK, Integer) Then
Throw New InvalidOperationException($"License validation failed [{errorCode}]: {errorMsg}")
End If
이후 — IronBarcode:
// NuGet: dotnet add package BarCode
using IronBarCode;
// Local validation — no network call, no error code
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
// NuGet: dotnet add package BarCode
using IronBarCode;
// Local validation — no network call, no error code
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode
' Local validation — no network call, no error code
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
ASP.NET Core 애플리케이션에서, 이것을 builder.Build() 전에 Program.cs에 추가하십시오:
IronBarCode.License.LicenseKey = Environment.GetEnvironmentVariable("IRONBARCODE_KEY")
?? "YOUR-LICENSE-KEY";
IronBarCode.License.LicenseKey = Environment.GetEnvironmentVariable("IRONBARCODE_KEY")
?? "YOUR-LICENSE-KEY";
Imports IronBarCode
IronBarCode.License.LicenseKey = If(Environment.GetEnvironmentVariable("IRONBARCODE_KEY"), "YOUR-LICENSE-KEY")
Docker 또는 Kubernetes 환경에서, 배포 매니페스트에 IRONBARCODE_KEY 환경 변수를 설정하십시오. 외부 네트워크 규칙이 필요하지 않습니다.
3단계: 네임스페이스 가져오기 바꾸기
모든 원본 파일에서 찾기 및 바꾸기:
grep -r "using Dynamsoft\." --include="*.cs" .
grep -r "using Dynamsoft\." --include="*.cs" .
각각의 항목을 바꾸십시오:
// Before
using Dynamsoft.CVR;
using Dynamsoft.DBR;
using Dynamsoft.License;
using Dynamsoft.Core;
// After
using IronBarCode;
// Before
using Dynamsoft.CVR;
using Dynamsoft.DBR;
using Dynamsoft.License;
using Dynamsoft.Core;
// After
using IronBarCode;
Imports IronBarCode
코드 마이그레이션 예제
기본 파일 읽기
가장 기본적인 작업은 이미지 파일에서 바코드를 읽는 것입니다.
이전 — 다이나모프트:
using Dynamsoft.CVR;
using Dynamsoft.DBR;
public string ReadBarcodeFromFile(CaptureVisionRouter router, string imagePath)
{
CapturedResult result = router.Capture(imagePath, PresetTemplate.PT_READ_BARCODES);
BarcodeResultItem[] items = result.GetDecodedBarcodesResult()?.GetItems();
if (items == null || items.Length == 0)
return null;
return items[0].GetText();
}
using Dynamsoft.CVR;
using Dynamsoft.DBR;
public string ReadBarcodeFromFile(CaptureVisionRouter router, string imagePath)
{
CapturedResult result = router.Capture(imagePath, PresetTemplate.PT_READ_BARCODES);
BarcodeResultItem[] items = result.GetDecodedBarcodesResult()?.GetItems();
if (items == null || items.Length == 0)
return null;
return items[0].GetText();
}
Imports Dynamsoft.CVR
Imports Dynamsoft.DBR
Public Function ReadBarcodeFromFile(router As CaptureVisionRouter, imagePath As String) As String
Dim result As CapturedResult = router.Capture(imagePath, PresetTemplate.PT_READ_BARCODES)
Dim items As BarcodeResultItem() = result.GetDecodedBarcodesResult()?.GetItems()
If items Is Nothing OrElse items.Length = 0 Then
Return Nothing
End If
Return items(0).GetText()
End Function
이후 — IronBarcode:
// NuGet: dotnet add package BarCode
using IronBarCode;
public string ReadBarcodeFromFile(string imagePath)
{
var results = BarcodeReader.Read(imagePath);
return results?.FirstOrDefault()?.Value;
}
// NuGet: dotnet add package BarCode
using IronBarCode;
public string ReadBarcodeFromFile(string imagePath)
{
var results = BarcodeReader.Read(imagePath);
return results?.FirstOrDefault()?.Value;
}
Imports IronBarCode
Public Function ReadBarcodeFromFile(imagePath As String) As String
Dim results = BarcodeReader.Read(imagePath)
Return results?.FirstOrDefault()?.Value
End Function
라우터 인스턴스가 사라졌습니다. BarcodeReader.Read는 정적입니다. BarcodeResultItem.GetText()는 .Value가 됩니다. results의 null 체크는 LINQ 덕분에 더 깔끔합니다.
여러 개의 바코드 읽기
이전 — 다이나모프트:
using Dynamsoft.CVR;
using Dynamsoft.DBR;
public List<string> ReadAllBarcodes(CaptureVisionRouter router, string imagePath)
{
SimplifiedCaptureVisionSettings settings = router.GetSimplifiedSettings(
PresetTemplate.PT_READ_BARCODES);
settings.BarcodeSettings.ExpectedBarcodesCount = 0; // 0 = find all
router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings);
CapturedResult result = router.Capture(imagePath, PresetTemplate.PT_READ_BARCODES);
BarcodeResultItem[] items = result.GetDecodedBarcodesResult()?.GetItems();
var values = new List<string>();
if (items != null)
{
foreach (var item in items)
values.Add(item.GetText());
}
return values;
}
using Dynamsoft.CVR;
using Dynamsoft.DBR;
public List<string> ReadAllBarcodes(CaptureVisionRouter router, string imagePath)
{
SimplifiedCaptureVisionSettings settings = router.GetSimplifiedSettings(
PresetTemplate.PT_READ_BARCODES);
settings.BarcodeSettings.ExpectedBarcodesCount = 0; // 0 = find all
router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings);
CapturedResult result = router.Capture(imagePath, PresetTemplate.PT_READ_BARCODES);
BarcodeResultItem[] items = result.GetDecodedBarcodesResult()?.GetItems();
var values = new List<string>();
if (items != null)
{
foreach (var item in items)
values.Add(item.GetText());
}
return values;
}
Imports Dynamsoft.CVR
Imports Dynamsoft.DBR
Public Function ReadAllBarcodes(router As CaptureVisionRouter, imagePath As String) As List(Of String)
Dim settings As SimplifiedCaptureVisionSettings = router.GetSimplifiedSettings(PresetTemplate.PT_READ_BARCODES)
settings.BarcodeSettings.ExpectedBarcodesCount = 0 ' 0 = find all
router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings)
Dim result As CapturedResult = router.Capture(imagePath, PresetTemplate.PT_READ_BARCODES)
Dim items As BarcodeResultItem() = result.GetDecodedBarcodesResult()?.GetItems()
Dim values As New List(Of String)()
If items IsNot Nothing Then
For Each item In items
values.Add(item.GetText())
Next
End If
Return values
End Function
이후 — IronBarcode:
using IronBarCode;
public List<string> ReadAllBarcodes(string imagePath)
{
var options = new BarcodeReaderOptions
{
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
return BarcodeReader.Read(imagePath, options)
.Select(r => r.Value)
.ToList();
}
using IronBarCode;
public List<string> ReadAllBarcodes(string imagePath)
{
var options = new BarcodeReaderOptions
{
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
return BarcodeReader.Read(imagePath, options)
.Select(r => r.Value)
.ToList();
}
Imports IronBarCode
Public Function ReadAllBarcodes(imagePath As String) As List(Of String)
Dim options As New BarcodeReaderOptions With {
.ExpectMultipleBarcodes = True,
.MaxParallelThreads = 4
}
Return BarcodeReader.Read(imagePath, options) _
.Select(Function(r) r.Value) _
.ToList()
End Function
바이트 단위(메모리 내 이미지)에서 읽기
이전 — 다이나모프트:
using Dynamsoft.CVR;
using Dynamsoft.Core;
using Dynamsoft.DBR;
// Requires width, height, stride, and pixel format — low-level buffer API
public string ReadFromBuffer(CaptureVisionRouter router, byte[] rawPixels, int width, int height)
{
var imageData = new ImageData
{
Bytes = rawPixels,
Width = width,
Height = height,
Stride = width * 3, // assuming 24bpp RGB
Format = EnumImagePixelFormat.IPF_RGB_888
};
CapturedResult result = router.Capture(imageData, PresetTemplate.PT_READ_BARCODES);
return result.GetDecodedBarcodesResult()?.GetItems()?.FirstOrDefault()?.GetText();
}
using Dynamsoft.CVR;
using Dynamsoft.Core;
using Dynamsoft.DBR;
// Requires width, height, stride, and pixel format — low-level buffer API
public string ReadFromBuffer(CaptureVisionRouter router, byte[] rawPixels, int width, int height)
{
var imageData = new ImageData
{
Bytes = rawPixels,
Width = width,
Height = height,
Stride = width * 3, // assuming 24bpp RGB
Format = EnumImagePixelFormat.IPF_RGB_888
};
CapturedResult result = router.Capture(imageData, PresetTemplate.PT_READ_BARCODES);
return result.GetDecodedBarcodesResult()?.GetItems()?.FirstOrDefault()?.GetText();
}
Imports Dynamsoft.CVR
Imports Dynamsoft.Core
Imports Dynamsoft.DBR
' Requires width, height, stride, and pixel format — low-level buffer API
Public Function ReadFromBuffer(router As CaptureVisionRouter, rawPixels As Byte(), width As Integer, height As Integer) As String
Dim imageData As New ImageData With {
.Bytes = rawPixels,
.Width = width,
.Height = height,
.Stride = width * 3, ' assuming 24bpp RGB
.Format = EnumImagePixelFormat.IPF_RGB_888
}
Dim result As CapturedResult = router.Capture(imageData, PresetTemplate.PT_READ_BARCODES)
Return result.GetDecodedBarcodesResult()?.GetItems()?.FirstOrDefault()?.GetText()
End Function
이후 — IronBarcode:
using IronBarCode;
// Pass PNG/JPEG/BMP bytes directly — no pixel format or stride calculation
public string ReadFromImageBytes(byte[] imageBytes)
{
return BarcodeReader.Read(imageBytes)?.FirstOrDefault()?.Value;
}
using IronBarCode;
// Pass PNG/JPEG/BMP bytes directly — no pixel format or stride calculation
public string ReadFromImageBytes(byte[] imageBytes)
{
return BarcodeReader.Read(imageBytes)?.FirstOrDefault()?.Value;
}
Imports IronBarCode
Public Function ReadFromImageBytes(imageBytes As Byte()) As String
Return BarcodeReader.Read(imageBytes)?.FirstOrDefault()?.Value
End Function
이전에 애플리케이션에서 이미지 바이트를 Dynamsoft용 원시 픽셀 버퍼로 변환한 경우, 먼저 원시 픽셀로 디코딩하지 않고 원래 인코딩된 이미지 바이트(PNG, JPEG, BMP)를 IronBarcode 에 직접 전달할 수 있습니다.
PDF 바코드 읽기 - 렌더링 루프 제거
이는 일반적으로 마이그레이션 과정에서 가장 큰 코드 감소 부분입니다. PdfiumViewer의 전체 렌더링 루프를 제거하고 단일 호출로 대체하십시오.
이전 — PDFiumViewer를 사용한 Dynamsoft:
// Requires: Dynamsoft.DotNet.BarcodeReader.Bundle + PdfiumViewer + PdfiumViewer.Native.*
using Dynamsoft.CVR;
using Dynamsoft.DBR;
using PdfiumViewer;
using System.Drawing.Imaging;
public List<string> ReadBarcodesFromPdf(CaptureVisionRouter router, string pdfPath)
{
var allBarcodes = new List<string>();
using (var pdfDoc = PdfDocument.Load(pdfPath))
{
for (int page = 0; page < pdfDoc.PageCount; page++)
{
using var image = pdfDoc.Render(page, 300, 300, true);
using var ms = new MemoryStream();
image.Save(ms, ImageFormat.Png);
CapturedResult result = router.Capture(ms.ToArray(),
PresetTemplate.PT_READ_BARCODES);
var items = result.GetDecodedBarcodesResult()?.GetItems();
if (items != null)
{
foreach (var item in items)
allBarcodes.Add(item.GetText());
}
}
}
return allBarcodes;
}
// Requires: Dynamsoft.DotNet.BarcodeReader.Bundle + PdfiumViewer + PdfiumViewer.Native.*
using Dynamsoft.CVR;
using Dynamsoft.DBR;
using PdfiumViewer;
using System.Drawing.Imaging;
public List<string> ReadBarcodesFromPdf(CaptureVisionRouter router, string pdfPath)
{
var allBarcodes = new List<string>();
using (var pdfDoc = PdfDocument.Load(pdfPath))
{
for (int page = 0; page < pdfDoc.PageCount; page++)
{
using var image = pdfDoc.Render(page, 300, 300, true);
using var ms = new MemoryStream();
image.Save(ms, ImageFormat.Png);
CapturedResult result = router.Capture(ms.ToArray(),
PresetTemplate.PT_READ_BARCODES);
var items = result.GetDecodedBarcodesResult()?.GetItems();
if (items != null)
{
foreach (var item in items)
allBarcodes.Add(item.GetText());
}
}
}
return allBarcodes;
}
Imports Dynamsoft.CVR
Imports Dynamsoft.DBR
Imports PdfiumViewer
Imports System.Drawing.Imaging
Public Function ReadBarcodesFromPdf(router As CaptureVisionRouter, pdfPath As String) As List(Of String)
Dim allBarcodes As New List(Of String)()
Using pdfDoc As PdfDocument = PdfDocument.Load(pdfPath)
For page As Integer = 0 To pdfDoc.PageCount - 1
Using image = pdfDoc.Render(page, 300, 300, True)
Using ms As New MemoryStream()
image.Save(ms, ImageFormat.Png)
Dim result As CapturedResult = router.Capture(ms.ToArray(), PresetTemplate.PT_READ_BARCODES)
Dim items = result.GetDecodedBarcodesResult()?.GetItems()
If items IsNot Nothing Then
For Each item In items
allBarcodes.Add(item.GetText())
Next
End If
End Using
End Using
Next
End Using
Return allBarcodes
End Function
이후 — IronBarcode:
using IronBarCode;
public List<string> ReadBarcodesFromPdf(string pdfPath)
{
return BarcodeReader.Read(pdfPath)
.Select(r => r.Value)
.ToList();
}
using IronBarCode;
public List<string> ReadBarcodesFromPdf(string pdfPath)
{
return BarcodeReader.Read(pdfPath)
.Select(r => r.Value)
.ToList();
}
Imports IronBarCode
Public Function ReadBarcodesFromPdf(pdfPath As String) As List(Of String)
Return BarcodeReader.Read(pdfPath) _
.Select(Function(r) r.Value) _
.ToList()
End Function
페이지 루프, PdfDocument, 300 DPI 렌더 단계, MemoryStream, 페이지 단위의 Capture 호출이 모두 사라집니다. IronBarcode PDF 페이지를 자체적으로 처리합니다.
(복잡하거나 복잡한 바코드의 경우) 옵션을 사용하여 PDF에서 읽어야 하는 경우:
using IronBarCode;
public List<string> ReadBarcodesFromPdfAccurate(string pdfPath)
{
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true
};
return BarcodeReader.Read(pdfPath, options)
.Select(r => r.Value)
.ToList();
}
using IronBarCode;
public List<string> ReadBarcodesFromPdfAccurate(string pdfPath)
{
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true
};
return BarcodeReader.Read(pdfPath, options)
.Select(r => r.Value)
.ToList();
}
Imports IronBarCode
Public Function ReadBarcodesFromPdfAccurate(pdfPath As String) As List(Of String)
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True
}
Return BarcodeReader.Read(pdfPath, options) _
.Select(Function(r) r.Value) _
.ToList()
End Function
오프라인/에어갭 배포
현재 코드에 오프라인 라이선스 패턴이 포함되어 있다면 완전히 제거하십시오.
이전 — Dynamsoft 오프라인 라이선스:
using Dynamsoft.License;
using Dynamsoft.Core;
// Dynamsoft offline: fetch license bundle on a connected machine, persist it,
// then replay it on the offline machine via InitLicenseFromLicenseContent.
int errorCode = LicenseManager.InitLicenseFromLicenseContent(
licenseContent,
out string errorMsg);
if (errorCode != (int)EnumErrorCode.EC_OK)
throw new InvalidOperationException($"Offline license failed: {errorMsg}");
using Dynamsoft.License;
using Dynamsoft.Core;
// Dynamsoft offline: fetch license bundle on a connected machine, persist it,
// then replay it on the offline machine via InitLicenseFromLicenseContent.
int errorCode = LicenseManager.InitLicenseFromLicenseContent(
licenseContent,
out string errorMsg);
if (errorCode != (int)EnumErrorCode.EC_OK)
throw new InvalidOperationException($"Offline license failed: {errorMsg}");
Imports Dynamsoft.License
Imports Dynamsoft.Core
' Dynamsoft offline: fetch license bundle on a connected machine, persist it,
' then replay it on the offline machine via InitLicenseFromLicenseContent.
Dim errorMsg As String
Dim errorCode As Integer = LicenseManager.InitLicenseFromLicenseContent(licenseContent, errorMsg)
If errorCode <> CType(EnumErrorCode.EC_OK, Integer) Then
Throw New InvalidOperationException($"Offline license failed: {errorMsg}")
End If
이후 — IronBarcode:
// Remove all of the above. Replace with:
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
// Remove all of the above. Replace with:
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
가져오고 갱신할 라이선스 콘텐츠 번들이 없습니다. 연결된 머신 부트스트랩 단계가 없습니다. 키는 로컬에서 검증됩니다.
Docker 구성
만약 Dynamsoft 라이선스 엔드포인트로의 HTTPS 외부 도메인 액세스를 허용하기 위한 네트워크 출구 규칙이나 프록시 구성, 혹은 이를 갖춘 네트워크를 이전에 가지고 있었다면:
# Before: Docker or Kubernetes egress policy
# Required: Allow outbound HTTPS to Dynamsoft licence endpoints
# After: Remove that egress rule.
# IronBarcode does not require outbound network access for license validation.
# Set license via environment variable
env:
- name: IRONBARCODE_KEY
valueFrom:
secretKeyRef:
name: ironbarcode-license
key: key
# Before: Docker or Kubernetes egress policy
# Required: Allow outbound HTTPS to Dynamsoft licence endpoints
# After: Remove that egress rule.
# IronBarcode does not require outbound network access for license validation.
# Set license via environment variable
env:
- name: IRONBARCODE_KEY
valueFrom:
secretKeyRef:
name: ironbarcode-license
key: key
인스턴스 관리 정리
Dynamsoft는 CaptureVisionRouter을(를) 중심으로 한 인스턴스 기반 API를 사용합니다. 코드가 서비스 클래스, 필드 초기화 프로그램 또는 DI 등록에 라우터 인스턴스를 생성하는 경우, 이 모든 것이 사라집니다:
이전 — Dynamsoft 인스턴스 관리:
using Dynamsoft.CVR;
using Dynamsoft.DBR;
using Dynamsoft.License;
using Dynamsoft.Core;
public class BarcodeService : IDisposable
{
private readonly CaptureVisionRouter _router;
public BarcodeService()
{
int errorCode = LicenseManager.InitLicense("KEY", out string errorMsg);
if (errorCode != (int)EnumErrorCode.EC_OK)
throw new InvalidOperationException(errorMsg);
_router = new CaptureVisionRouter();
var settings = _router.GetSimplifiedSettings(PresetTemplate.PT_READ_BARCODES);
settings.BarcodeSettings.ExpectedBarcodesCount = 0;
_router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings);
}
public string[] ReadFile(string path)
{
CapturedResult result = _router.Capture(path, PresetTemplate.PT_READ_BARCODES);
var items = result.GetDecodedBarcodesResult()?.GetItems();
return items?.Select(i => i.GetText()).ToArray() ?? Array.Empty<string>();
}
public void Dispose()
{
_router?.Dispose();
}
}
using Dynamsoft.CVR;
using Dynamsoft.DBR;
using Dynamsoft.License;
using Dynamsoft.Core;
public class BarcodeService : IDisposable
{
private readonly CaptureVisionRouter _router;
public BarcodeService()
{
int errorCode = LicenseManager.InitLicense("KEY", out string errorMsg);
if (errorCode != (int)EnumErrorCode.EC_OK)
throw new InvalidOperationException(errorMsg);
_router = new CaptureVisionRouter();
var settings = _router.GetSimplifiedSettings(PresetTemplate.PT_READ_BARCODES);
settings.BarcodeSettings.ExpectedBarcodesCount = 0;
_router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings);
}
public string[] ReadFile(string path)
{
CapturedResult result = _router.Capture(path, PresetTemplate.PT_READ_BARCODES);
var items = result.GetDecodedBarcodesResult()?.GetItems();
return items?.Select(i => i.GetText()).ToArray() ?? Array.Empty<string>();
}
public void Dispose()
{
_router?.Dispose();
}
}
Imports Dynamsoft.CVR
Imports Dynamsoft.DBR
Imports Dynamsoft.License
Imports Dynamsoft.Core
Public Class BarcodeService
Implements IDisposable
Private ReadOnly _router As CaptureVisionRouter
Public Sub New()
Dim errorCode As Integer = LicenseManager.InitLicense("KEY", errorMsg:=Nothing)
If errorCode <> CType(EnumErrorCode.EC_OK, Integer) Then
Throw New InvalidOperationException(errorMsg)
End If
_router = New CaptureVisionRouter()
Dim settings = _router.GetSimplifiedSettings(PresetTemplate.PT_READ_BARCODES)
settings.BarcodeSettings.ExpectedBarcodesCount = 0
_router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings)
End Sub
Public Function ReadFile(path As String) As String()
Dim result As CapturedResult = _router.Capture(path, PresetTemplate.PT_READ_BARCODES)
Dim items = result.GetDecodedBarcodesResult()?.GetItems()
Return If(items?.Select(Function(i) i.GetText()).ToArray(), Array.Empty(Of String)())
End Function
Public Sub Dispose() Implements IDisposable.Dispose
_router?.Dispose()
End Sub
End Class
이후 — IronBarcode 정적 API:
// NuGet: dotnet add package BarCode
using IronBarCode;
public class BarcodeService
{
// No constructor initialization — license set once at app startup
// No Dispose — no instance to clean up
public string[] ReadFile(string path)
{
var options = new BarcodeReaderOptions { ExpectMultipleBarcodes = true };
return BarcodeReader.Read(path, options)
.Select(r => r.Value)
.ToArray();
}
}
// NuGet: dotnet add package BarCode
using IronBarCode;
public class BarcodeService
{
// No constructor initialization — license set once at app startup
// No Dispose — no instance to clean up
public string[] ReadFile(string path)
{
var options = new BarcodeReaderOptions { ExpectMultipleBarcodes = true };
return BarcodeReader.Read(path, options)
.Select(r => r.Value)
.ToArray();
}
}
Imports IronBarCode
Public Class BarcodeService
' No constructor initialization — license set once at app startup
' No Dispose — no instance to clean up
Public Function ReadFile(path As String) As String()
Dim options As New BarcodeReaderOptions With {.ExpectMultipleBarcodes = True}
Return BarcodeReader.Read(path, options) _
.Select(Function(r) r.Value) _
.ToArray()
End Function
End Class
이 클래스는 생성자, IDisposable 구현 및 _router 필드를 잃습니다. 이 서비스가 DI에 단일 인스턴스나 범위 지정된 서비스로 라우터 수명을 관리하도록 등록된 경우, 이 등록은 단순화될 수 있으며 서비스는 일련의 정적 메서드가 될 수 있습니다.
읽기 속도와 타임아웃 매핑
Dynamsoft는 밀리초 단위의 Timeout을 사용하여 카메라 프레임 속도에 최적화되어 있습니다. IronBarcode는 ReadingSpeed 열거형을 사용합니다:
| 다이나모프 설정 | IronBarcode 와 동등한 기능 |
|---|---|
settings.Timeout = 100 (카메라 파이프라인) |
Speed = ReadingSpeed.Faster |
| 타임아웃 시간 최소화 (속도 우선) | Speed = ReadingSpeed.Balanced |
| 타임아웃 시간 연장 (정확도 우선) | Speed = ReadingSpeed.Detailed |
| 최대한의 정확성, 시간 압박 없음 | Speed = ReadingSpeed.ExtremeDetail |
처리량이 100ms 이하의 응답 시간보다 중요한 대부분의 문서 처리 워크플로에서, ReadingSpeed.Balanced는 올바른 기본값입니다:
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True,
.MaxParallelThreads = 4
}
일반적인 마이그레이션 문제
BarcodeResultItem.GetText() vs result.Value
액세서는 메서드에서 속성으로 변경됩니다:
// Before
string value = item.GetText();
// After
string value = result.Value;
// Before
string value = item.GetText();
// After
string value = result.Value;
' Before
Dim value As String = item.GetText()
' After
Dim value As String = result.Value
BarcodeResultItem.GetFormatString() vs result.Format
Dynamsoft는 GetFormatString()을 통해 문자열로 형식을 반환합니다. IronBarcode는 result.Format에 BarcodeEncoding 열거형으로 그 형식을 노출합니다:
// Before
if (item.GetFormatString() == "QR_CODE")
Console.WriteLine("Found QR code");
// After
if (result.Format == BarcodeEncoding.QRCode)
Console.WriteLine("Found QR code");
// For logging without enum comparison — .ToString() works on both
Console.WriteLine($"Format: {result.Format}");
// Before
if (item.GetFormatString() == "QR_CODE")
Console.WriteLine("Found QR code");
// After
if (result.Format == BarcodeEncoding.QRCode)
Console.WriteLine("Found QR code");
// For logging without enum comparison — .ToString() works on both
Console.WriteLine($"Format: {result.Format}");
' Before
If item.GetFormatString() = "QR_CODE" Then
Console.WriteLine("Found QR code")
End If
' After
If result.Format = BarcodeEncoding.QRCode Then
Console.WriteLine("Found QR code")
End If
' For logging without enum comparison — .ToString() works on both
Console.WriteLine($"Format: {result.Format}")
null 결과 vs 빈 컬렉션
Dynamsoft의 GetDecodedBarcodesResult()는 바코드가 발견되지 않았을 때 null를 반환할 수 있습니다. IronBarcode 빈 컬렉션을 반환합니다. null 검사 업데이트:
// Before: null check required
CapturedResult result = router.Capture(path, PresetTemplate.PT_READ_BARCODES);
var items = result.GetDecodedBarcodesResult()?.GetItems();
if (items != null && items.Length > 0)
Process(items[0].GetText());
// After: null-safe but also correct to check Count
var results = BarcodeReader.Read(path);
if (results.Any())
Process(results.First().Value);
// Before: null check required
CapturedResult result = router.Capture(path, PresetTemplate.PT_READ_BARCODES);
var items = result.GetDecodedBarcodesResult()?.GetItems();
if (items != null && items.Length > 0)
Process(items[0].GetText());
// After: null-safe but also correct to check Count
var results = BarcodeReader.Read(path);
if (results.Any())
Process(results.First().Value);
Imports System.Linq
' Before: null check required
Dim result As CapturedResult = router.Capture(path, PresetTemplate.PT_READ_BARCODES)
Dim items = result.GetDecodedBarcodesResult()?.GetItems()
If items IsNot Nothing AndAlso items.Length > 0 Then
Process(items(0).GetText())
End If
' After: null-safe but also correct to check Count
Dim results = BarcodeReader.Read(path)
If results.Any() Then
Process(results.First().Value)
End If
SimplifiedCaptureVisionSettings to BarcodeReaderOptions
GetSimplifiedSettings / UpdateSettings 패턴은 Read에 전달되는 BarcodeReaderOptions가 됩니다:
// Before
var settings = router.GetSimplifiedSettings(PresetTemplate.PT_READ_BARCODES);
settings.BarcodeSettings.ExpectedBarcodesCount = 0;
settings.Timeout = 500;
router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings);
var result = router.Capture(path, PresetTemplate.PT_READ_BARCODES);
// After
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true
};
var results = BarcodeReader.Read(path, options);
// Before
var settings = router.GetSimplifiedSettings(PresetTemplate.PT_READ_BARCODES);
settings.BarcodeSettings.ExpectedBarcodesCount = 0;
settings.Timeout = 500;
router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings);
var result = router.Capture(path, PresetTemplate.PT_READ_BARCODES);
// After
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true
};
var results = BarcodeReader.Read(path, options);
' Before
Dim settings = router.GetSimplifiedSettings(PresetTemplate.PT_READ_BARCODES)
settings.BarcodeSettings.ExpectedBarcodesCount = 0
settings.Timeout = 500
router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings)
Dim result = router.Capture(path, PresetTemplate.PT_READ_BARCODES)
' After
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True
}
Dim results = BarcodeReader.Read(path, options)
마이그레이션 체크리스트
업데이트가 필요한 모든 Dynamsoft 참조 자료를 찾으려면 다음 검색을 실행하세요.
grep -r "using Dynamsoft\." --include="*.cs" .
grep -r "LicenseManager.InitLicense\|EnumErrorCode\|EC_OK" --include="*.cs" .
grep -r "new CaptureVisionRouter\|router\.Capture\|PresetTemplate" --include="*.cs" .
grep -r "BarcodeResultItem\|GetDecodedBarcodesResult\|GetFormatString" --include="*.cs" .
grep -r "GetSimplifiedSettings\|UpdateSettings\|SimplifiedCaptureVisionSettings" --include="*.cs" .
grep -r "router\.Dispose\|InitLicenseFromLicenseContent" --include="*.cs" .
grep -r "using Dynamsoft\." --include="*.cs" .
grep -r "LicenseManager.InitLicense\|EnumErrorCode\|EC_OK" --include="*.cs" .
grep -r "new CaptureVisionRouter\|router\.Capture\|PresetTemplate" --include="*.cs" .
grep -r "BarcodeResultItem\|GetDecodedBarcodesResult\|GetFormatString" --include="*.cs" .
grep -r "GetSimplifiedSettings\|UpdateSettings\|SimplifiedCaptureVisionSettings" --include="*.cs" .
grep -r "router\.Dispose\|InitLicenseFromLicenseContent" --include="*.cs" .
각 경기를 하나씩 살펴보세요:
using Dynamsoft.*→using IronBarCodeLicenseManager.InitLicense(key, out errorMsg)+ 오류 체크 →IronBarCode.License.LicenseKey = "key"new CaptureVisionRouter()→ 제거 (정적 API, 인스턴스 필요 없음)router.Capture(path, PresetTemplate.PT_READ_BARCODES)→BarcodeReader.Read(path)router.Capture(imageData, ...)(원시 픽셀 버퍼) →BarcodeReader.Read(imageBytes)- 페이지별 PDF 렌더 루프 +
router.Capture(pageBytes, ...)→BarcodeReader.Read(pdfPath) BarcodeResultItem.GetText()→result.ValueBarcodeResultItem.GetFormatString()→result.FormatGetSimplifiedSettings(...)+UpdateSettings(...)→new BarcodeReaderOptions { ... }router.Dispose()→ 제거LicenseManager.InitLicenseFromLicenseContent(...)→ 완전히 제거- Dynamsoft PDF 처리를 지원하기 위해 추가된 PdfiumViewer NuGet 패키지를 제거합니다.
- Dynamsoft 라이선스 엔드포인트의 Docker/Kubernetes 네트워크 유출 규칙 제거
- 배포 설정에서
IRONBARCODE_KEY환경 변수를 설정하십시오
자주 묻는 질문
Dynamsoft 바코드 리더에서 IronBarcode로 마이그레이션해야 하는 이유는 무엇인가요?
일반적인 이유로는 라이선스 간소화(SDK + 런타임 키 복잡성 제거), 처리량 제한 제거, 네이티브 PDF 지원 확보, Docker/CI/CD 배포 개선, 프로덕션 코드의 API 상용구 감소 등이 있습니다.
Dynamsoft API 호출을 IronBarcode로 대체하려면 어떻게 해야 하나요?
인스턴스 생성 및 라이선스 상용구를 IronBarCode.License.LicenseKey = "key"로 대체합니다. 판독기 호출을 BarcodeReader.Read(경로)로, 쓰기 호출을 BarcodeWriter.CreateBarcode(데이터, 인코딩)로 바꿉니다. 정적 메서드는 인스턴스 관리가 필요하지 않습니다.
Dynamsoft 바코드 리더에서 IronBarcode로 마이그레이션할 때 얼마나 많은 코드가 변경되나요?
대부분의 마이그레이션은 더 적은 코드 줄로 이루어집니다. 라이선스 상용구, 인스턴스 생성자, 명시적 형식 구성이 제거됩니다. 핵심 읽기/쓰기 작업이 더 간결한 결과 객체를 가진 더 짧은 IronBarcode에 매핑됩니다.
마이그레이션하는 동안 Dynamsoft 바코드 리더와 IronBarcode를 모두 설치해야 하나요?
아니요. 대부분의 마이그레이션은 병렬 작업이 아닌 직접 교체 작업입니다. 한 번에 하나의 서비스 클래스를 마이그레이션하고, NuGet 참조를 교체하고, 인스턴스화 및 API 호출 패턴을 업데이트한 후 다음 클래스로 이동합니다.
IronBarcode의 NuGet 패키지 이름은 무엇인가요?
패키지는 'IronBarCode'(대문자 B와 C 포함)입니다. '설치-패키지 IronBarCode' 또는 '닷넷 추가 패키지 IronBarCode'로 설치합니다. 코드의 사용 지시어는 'using IronBarCode;'입니다.
Dynamsoft 바코드 리더와 비교했을 때 IronBarcode는 어떻게 Docker 배포를 간소화하나요?
IronBarcode는 외부 SDK 파일이나 마운트된 라이선스 구성이 없는 NuGet 패키지입니다. Docker에서 IRONBARCODE_LICENSE_KEY 환경 변수를 설정하면 패키지가 시작 시 라이선스 유효성 검사를 처리합니다.
Dynamsoft에서 마이그레이션한 후 IronBarcode가 모든 바코드 형식을 자동으로 감지하나요?
예. IronBarcode는 지원되는 모든 형식에서 기호를 자동으로 감지합니다. 명시적인 바코드 유형 열거가 필요하지 않습니다. 형식이 이미 알려져 있고 성능이 중요한 경우 BarcodeReaderOptions를 사용하여 검색 공간을 최적화하여 제한할 수 있습니다.
IronBarcode는 별도의 라이브러리 없이 PDF에서 바코드를 판독할 수 있나요?
예. BarcodeReader.Read("document.pdf")는 기본적으로 PDF 파일을 처리합니다. 결과에는 발견된 각 바코드에 대한 페이지 번호, 형식, 값 및 신뢰도가 포함됩니다. 외부 PDF 렌더링 단계가 필요하지 않습니다.
IronBarcode는 병렬 바코드 처리를 어떻게 처리하나요?
IronBarcode의 정적 메서드는 상태 저장소가 없고 스레드에 안전합니다. 스레드별 인스턴스 관리 없이 파일 목록에 직접 Parallel.ForEach를 사용할 수 있습니다. BarcodeReaderOptions.MaxParallelThreads는 내부 스레드 예산을 제어합니다.
Dynamsoft 바코드 리더에서 IronBarcode로 마이그레이션하면 어떤 결과 속성이 변경되나요?
일반적인 이름 변경: 바코드 값은 값으로, 바코드 유형은 형식으로 바뀝니다. IronBarcode 결과에는 신뢰도 및 페이지 번호도 추가됩니다. 솔루션 전반의 검색 및 바꾸기 기능은 기존 결과 처리 코드에서 이름 변경을 처리합니다.
CI/CD 파이프라인에서 IronBarcode 라이선싱을 설정하려면 어떻게 해야 하나요?
IRONBARCODE_LICENSE_KEY를 파이프라인 시크릿으로 저장하고 애플리케이션 시작 코드에 IronBarCode.License.LicenseKey를 할당하세요. 하나의 비밀은 개발, 테스트, 스테이징 및 프로덕션을 포함한 모든 환경에 적용됩니다.
IronBarcode는 사용자 지정 스타일로 QR 코드 생성을 지원하나요?
예. QRCodeWriter.CreateQrCode()는 변경바코드색()을 통한 사용자 지정 색상, 추가브랜드 로고()를 통한 로고 임베딩, 구성 가능한 오류 수정 수준, PNG, JPG, PDF, 스트림을 포함한 여러 출력 형식을 지원합니다.

