IRONSOFTWAREHOME
동영상

C#에서 비동기 및 멀티스레딩을 사용하는 방법

칸나오팟 우돈판트
Kannapat Udonpant
Updated: 2026년 8월 1일

Mindee에서 IronOCR 로 마이그레이션하면 문서 처리가 외부 클라우드 서버에서 자체 인프라로 이전되어 페이지당 요금 청구, 타사 데이터 전송 및 런타임 시 네트워크 가용성 종속성이 사라집니다. 아래 섹션에서는 패키지 교체, 네임스페이스 업데이트, 그리고 송장 영역 추출, 다중 페이지 영수증 PDF 처리, 재무 문서 사전 처리, 검색 가능한 PDF 아카이빙 등 네 가지 실제 코드 변경 전후 시나리오를 다룹니다.

Mindee에서 다른 곳으로 옮겨야 하는 이유는 무엇일까요?

Mindee는 실제 문제를 우아하게 해결합니다. 문서를 제출하면 구조화된 JSON 필드를 받아볼 수 있습니다. 재무 문서를 외부 API로 전송하는 것이 허용되고 전송량이 적당한 수준인 팀의 경우, 이 방법은 빠른 결과를 제공합니다. 마이그레이션 트리거는 일반적으로 여러 조건 중 하나가 변경될 때 발생합니다.

재무 데이터는 준수 경계를 넘습니다. Mindee의 ParseAsync<InvoiceV4>은(는) 전체 문서를 외부 서버에 업로드합니다. IBAN 코드, 라우팅 번호, 공급업체 EIN 및 상세 품목 정보는 공용 인터넷을 통해 전송되며 사용자가 제어할 수 없는 하드웨어에서 처리됩니다. SOC 2 Type II 인증은 Mindee가 보안 관행을 준수함을 확인시켜 줍니다. 이 기능은 문서를 보안 영역 내에 안전하게 보관하지 않습니다. 규정 준수 검토, 신규 고객 계약 또는 데이터 상주 규정에서 제3자 클라우드 처리를 금지하는 경우, Mindee의 아키텍처는 데이터 추출 정확도와 관계없이 부적격 판정을 받게 됩니다.

페이지당 비용은 사용량에 따라 불리하게 작용합니다. 스타터 플랜은 월 49달러에 월 1,000페이지를 제공합니다. 프로 플랜은 월 499달러에 월 5,000페이지를 제공합니다. 여러 페이지로 구성된 PDF 파일은 모든 페이지 수를 계산합니다. 개발 실행 횟수는 할당량에 포함됩니다. 한 달에 4,000건의 송장을 처리하는 팀은 월 499달러, 연간 5,988달러를 지불하며, 이 금액은 매년 재설정되고 처리량이 증가할 때마다 인상됩니다. 월 24,000페이지 분량이라면 Enterprise 가격으로 협상하시는 겁니다. IronOCR의 영구 라이선스는 1,499달러(Professional 등급)이며, 무제한 문서 용량을 지원하고 민디 Pro 대비 4개월 이내에 투자 비용을 회수할 수 있습니다.

비동기 폴링은 스택 전체에 전파됩니다. Mindee의 모든 작업은 네트워크 요청이므로 비동기적으로 처리됩니다. 이러한 필수적인 비동기 처리는 컨트롤러, 서비스 계층, 워커 클래스를 거쳐 상위 계층으로 전파됩니다. 네트워크를 사용할 수 없거나 민디 서비스에 장애가 발생하면, 연쇄적인 오류로 인해 로컬 백업 시스템 없이 전체 시스템이 마비됩니다. IronOCR은 동기식으로 처리되며, 필요할 경우 아키텍처 일관성을 위해 Task.Run로 래핑합니다.

사전 구축된 API 카탈로그는 한계가 있습니다. Mindee는 InvoiceV4, ReceiptV5, PassportV1 및 기타 문서 유형의 작은 카탈로그를 포함합니다. 그 목록 외의 문서 유형은 Enterprise 플랜 사용자 정의 모델 학습: 샘플 수집, 라벨링, 학습 시간, API 사용 가능 이전의 리드 타임이 필요합니다. 귀사에서 필요로 하는 새로운 문서 유형이 생길 때마다 별도의 업체와 계약을 체결해야 합니다. IronOCR은 동일한 IronTesseract().Read() 호출을 사용하여 모든 문서 유형을 처리합니다. 새로운 문서 유형을 추가한다는 것은 추출 패턴을 작성하는 것을 의미하며, 교육 계약을 협상하는 것을 의미하지 않습니다.

API 키 관리는 운영 측면을 강화합니다. 민디 자격 증명은 서버 측에 안전하게 저장하고, 주기적으로 갱신하며, 노출되지 않도록 보호해야 합니다. 네트워크 송신 규칙은 민디 엔드포인트로의 HTTPS 아웃바운드 전송을 허용해야 합니다. 재시도 로직은 피할 수 없는 네트워크 실패로 인한 HttpRequestExceptionMindeeException를 처리해야 합니다. Mindee를 제거하면 자격 증명, 송신 규칙, 네트워크 I/O에 대한 재시도 래퍼 등 운영상의 표면적인 문제가 모두 사라집니다.

인터넷 연결이 차단된 환경 및 제한된 환경에서는 Mindee를 사용할 수 없습니다. 정부 계약업체, 방위산업 하청업체, 엄격한 인터넷 차단이 적용되는 의료 네트워크, 안정적인 인터넷 연결이 없는 시설에 설치된 산업 시스템은 Mindee를 설계된 대로 사용할 수 없습니다.IronOCR외부 액세스가 없는 Docker 컨테이너, 송신 제한이 있는 Azure Functions, 그리고 완전히 격리된 환경에서 동일하게 실행됩니다. 실행 시 클라우드 종속성이 없습니다. 배포 등급에 대한 자세한 내용은 IronOCR 라이선스 페이지를 참조하십시오.

근본적인 문제

Mindee에서 처리하는 모든 금융 문서는 사용자가 제어할 수 없는 네트워크 경계를 통과합니다.

// Mindee: invoice with bank details leaves your infrastructure on this line
var response = await _client.ParseAsync<InvoiceV4>(new LocalInputSource("invoice.pdf"));
// IBAN, routing number, EIN, line items — all transmitted to 민디 cloud
C#
// IronOCR: same invoice, same result, zero data transmission
var result = new IronTesseract().Read("invoice.pdf");
// All processing local — bank details never leave your machine
C#

##IronOCR과 Mindee: 기능 비교

다음 표는 마이그레이션 결정에 영향을 미치는 아키텍처 및 기능상의 차이점을 보여줍니다.

기능민디IronOCR
처리 위치민디 클라우드 서버로컬 머신 / 인프라
실행 시 인터넷 연결이 필요합니다.항상절대
데이터 전송통화당 전체 문서가 업로드됩니다.None
문서당 비용예 (페이지당, 요금제 기준)아니요 (영구 라이선스)
시작 가격월 49달러 (1,000페이지)$999 일회성 (Lite)
오프라인/에어갭 지원지원되지 않음전체 지원
온프레미스 배포사용 불가유일한 선택
송장 분석사전 구축된 구조화된 API (InvoiceV4)OCR + 영역 기반 또는 정규 표현식 추출
영수증 분석사전 구축된 구조화된 API (ReceiptV5)OCR + 추출 패턴
임의의 문서 유형맞춤형 학습 없이는 지원되지 않습니다.모든 문서에 대한 완벽한 지원
사용자 지정 모델 학습Enterprise 계획 + 소요 기간필요하지 않음
API 호출 패턴비동기 필수(네트워크 I/O)동기식 (비동기식 선택 사항)
속도 제한계획에 따름None
PDF 입력예 (네이티브, 변환 없음)
다중 페이지 PDF 처리
검색 가능한 PDF 출력아니요예 (result.SaveAsSearchablePdf())
이미지 전처리노출된 것 없음기울기 보정, 노이즈 제거, 대비 조정, 이진화, 선명도 향상, 크기 조정
영역 기반 추출응답에 대한 필드 좌표CropRectangle 입력 시
125개 이상의 언어 지원제한적예 (번들형이며, tessdata 관리 기능은 포함되지 않습니다)
바코드 판독아니요예 (OCR과 동시에 진행됨)
구조화된 단어 좌표아니요예 (페이지, 단락, 줄, 단어)
스레드 안전성해당 없음 (통화당 네트워크 I/O)내장형
크로스 플랫폼클라우드(플랫폼 독립적)윈도우, 리눅스, macOS, Docker, Azure, AWS
.NET 호환성.NET Standard 2.0 이상.NET Framework 4.6.2 이상, .NET 5/6/7/8/9
상업적 지원

빠른 시작: Mindee에서IronOCR로 마이그레이션

1단계: NuGet 패키지 교체

Mindee 패키지를 제거하세요:

dotnet remove package Mindee
SHELL

NuGet 에서IronOCR설치하세요.

dotnet add package IronOcr

단계 2: 네임스페이스 업데이트

Mindee 네임스페이스 블록을IronOCR네임스페이스로 교체하십시오.

// Before (Mindee)
using Mindee;
using Mindee.Input;
using Mindee.Product.Invoice;
using Mindee.Product.Receipt;
using Mindee.Product.FinancialDocument;

// After (IronOCR)
using IronOcr;
C#

단계 3: 라이선스 초기화

애플리케이션 시작 시(첫 번째 OCR 호출 전) 라이선스 키를 추가하십시오.

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

코드 마이그레이션 예제

문서 영역을 이용한 송장 필드 추출

Mindee는 서버 측 모델이 송장 번호, 날짜 및 합계가 일반적으로 나타나는 위치를 알고 있기 때문에 미리 구문 분석된 필드를 알려진 위치에 반환합니다.IronOCR등가는 문서를 전송하지 않고 Mindee의 추출을 공간 인식성과 일치시키기 위해 특정 영역을 읽기 위해 CropRectangle을 사용합니다.

돌봄 제공자 접근 방식:

using Mindee;
using Mindee.Input;
using Mindee.Product.Invoice;

public class MindeeZoneExtractor
{
    private readonly MindeeClient _client;

    public MindeeZoneExtractor(string apiKey)
    {
        _client = new MindeeClient(apiKey);
    }

    public async Task<(string invoiceNumber, string supplierName, decimal? total)>
        ExtractKeyFieldsAsync(string filePath)
    {
        // Document transmitted to 민디 — spatial field detection happens server-side
        var inputSource = new LocalInputSource(filePath);
        var response    = await _client.ParseAsync<InvoiceV4>(inputSource);
        var prediction  = response.Document.Inference.Prediction;

        // Fields arrive pre-parsed; no zone configuration required on your end
        return (
            prediction.InvoiceNumber?.Value,
            prediction.SupplierName?.Value,
            prediction.TotalAmount?.Value
        );
    }
}
C#

IronOCR 접근 방식:

using IronOcr;
using System.Text.RegularExpressions;

public class IronOcrZoneExtractor
{
    private readonly IronTesseract _ocr = new IronTesseract();

    public (string invoiceNumber, string supplierName, string total)
        ExtractKeyFields(string filePath)
    {
        // Zone 1: supplier name — top 12% of document, full width
        var headerRegion = new CropRectangle(0, 0, 850, 120);
        using var headerInput = new OcrInput();
        headerInput.LoadImage(filePath, headerRegion);
        var supplierResult = _ocr.Read(headerInput);

        // Zone 2: invoice number and date — upper-right quadrant
        var metaRegion = new CropRectangle(450, 80, 400, 100);
        using var metaInput = new OcrInput();
        metaInput.LoadImage(filePath, metaRegion);
        var metaResult = _ocr.Read(metaInput);

        // Zone 3: totals block — bottom-right 20%
        var totalsRegion = new CropRectangle(500, 800, 350, 200);
        using var totalsInput = new OcrInput();
        totalsInput.LoadImage(filePath, totalsRegion);
        var totalsResult = _ocr.Read(totalsInput);

        var invoiceNumber = Regex.Match(
            metaResult.Text,
            @"Invoice\s*#?\s*:?\s*([A-Z0-9\-]+)",
            RegexOptions.IgnoreCase).Groups[1].Value;

        var total = Regex.Match(
            totalsResult.Text,
            @"Total\s*(?:Due)?\s*:?\s*\$?([\d,]+\.?\d*)",
            RegexOptions.IgnoreCase).Groups[1].Value;

        // Supplier name is the first substantial text line in the header zone
        var supplierName = supplierResult.Text
            .Split('\n')
            .FirstOrDefault(l => l.Trim().Length > 4)
            ?.Trim();

        return (invoiceNumber, supplierName, total);
    }
}
C#

영역 기반 OCR은 Mindee의 공간 필드 감지 의도와 일치합니다. 즉, 전체 페이지에 정규식을 적용하는 대신 문서의 특정 영역을 읽습니다. CropRectangle(x, y, width, height)은(는) 픽셀 좌표를 가져오기 때문에 조정은 샘플 송장에 대해 측정해야 합니다. 영역 기반 OCR 가이드는 좌표 측정과 영역 겹침 전략을 다룹니다. 레이아웃이 가변적인 송장의 경우, 영역 추출을 result.Text에서 전체 페이지 정규식과 결합하면 가장 신뢰할 수 있는 결과가 생성됩니다.

여러 페이지로 구성된 경비 보고서 PDF 처리

Mindee는 PDF 파일을 입력받아 각 페이지를 개별 문서 단위로 처리하고, 페이지별로 구조화된 결과를 반환합니다. IronOCR은 다페이지 PDF를 OcrInput.LoadPdf()을 통해 본래적으로 읽고, 모든 페이지를 한 번의 호출로 처리하며, 페이지별 콘텐츠와 단어 좌표가 포함된 result.Pages을 반환합니다.

돌봄 제공자 접근 방식:

using Mindee;
using Mindee.Input;
using Mindee.Product.Receipt;

public class MindeeExpenseReportProcessor
{
    private readonly MindeeClient _client;

    public MindeeExpenseReportProcessor(string apiKey)
    {
        _client = new MindeeClient(apiKey);
    }

    public async Task<List<ExpenseSummary>> ProcessExpenseReportAsync(string pdfPath)
    {
        var summaries = new List<ExpenseSummary>();

        // 민디 processes per-document; each page of a PDF is a separate upload
        // For a 10-page expense report: 10 API calls, 10 pages billed
        var inputSource = new LocalInputSource(pdfPath);
        var response    = await _client.ParseAsync<ReceiptV5>(inputSource);

        var prediction = response.Document.Inference.Prediction;

        summaries.Add(new ExpenseSummary
        {
            MerchantName  = prediction.SupplierName?.Value,
            Date          = prediction.Date?.Value?.ToString(),
            TotalAmount   = prediction.TotalAmount?.Value ?? 0m,
            Category      = prediction.Category?.Value
        });

        return summaries;
    }
}
C#

IronOCR 접근 방식:

using IronOcr;
using System.Text.RegularExpressions;

public class IronOcrExpenseReportProcessor
{
    private readonly IronTesseract _ocr = new IronTesseract();

    public List<ExpenseSummary> ProcessExpenseReport(string pdfPath)
    {
        // Load entire multi-page PDF in one call — no per-page upload
        using var input = new OcrInput();
        input.LoadPdf(pdfPath);    // all pages loaded locally

        var result    = _ocr.Read(input);
        var summaries = new List<ExpenseSummary>();

        // Each page maps to one receipt in the expense report
        foreach (var page in result.Pages)
        {
            var pageText = page.Text;

            // Skip pages without receipt content
            if (!pageText.Contains("Total", StringComparison.OrdinalIgnoreCase))
                continue;

            var merchantName = page.Lines
                .FirstOrDefault(l => l.Text.Trim().Length > 4)
                ?.Text.Trim();

            var totalMatch = Regex.Match(
                pageText,
                @"(?:Total|Amount\s+Due|Grand\s+Total)\s*:?\s*\$?([\d,]+\.\d{2})",
                RegexOptions.IgnoreCase);

            var dateMatch = Regex.Match(
                pageText,
                @"\b(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})\b");

            var categoryMatch = Regex.Match(
                pageText,
                @"(?:Category|Dept|Department)\s*:?\s*(.+)",
                RegexOptions.IgnoreCase);

            summaries.Add(new ExpenseSummary
            {
                PageNumber   = page.PageNumber,
                MerchantName = merchantName,
                Date         = dateMatch.Success ? dateMatch.Value : null,
                TotalAmount  = totalMatch.Success
                    ? decimal.Parse(totalMatch.Groups[1].Value.Replace(",", ""))
                    : 0m,
                Category     = categoryMatch.Success
                    ? categoryMatch.Groups[1].Value.Trim()
                    : null,
                Confidence   = page.Words.Any()
                    ? page.Words.Average(w => (double)w.Confidence)
                    : 0
            });
        }

        return summaries;
    }
}

public class ExpenseSummary
{
    public int    PageNumber   { get; set; }
    public string MerchantName { get; set; }
    public string Date         { get; set; }
    public decimal TotalAmount { get; set; }
    public string Category     { get; set; }
    public double Confidence   { get; set; }
}
C#

Mindee를 사용하여 10페이지 분량의 경비 보고서 PDF 파일을 처리하면 10번의 API 호출이 발생하고 10페이지 분량의 비용이 청구됩니다.IronOCR페이지당 비용이나 페이지당 네트워크 왕복 없이 단일 로컬 호출로 동일한 파일을 처리합니다. result.Pages 컬렉션은 레이아웃 기반 추출을 위한 페이지별 텍스트, 단어 레벨 경계 상자 및 줄 위치를 제공합니다. 암호로 보호된 PDF 파일을 불러오거나 페이지 범위를 선택하는 방법에 대해서는 PDF 입력 가이드를 , 단어 좌표를 사용하는 방법에 대해서는 구조화된 읽기 결과 가이드를 참조하십시오.

스캔된 송장 사전 처리 파이프라인

Mindee의 클라우드 처리 기능은 필드 추출을 실행하기 전에 자체적인 이미지 정규화를 적용합니다. 해당 정규화의 품질은 불투명합니다. 사용자는 이를 제어할 수 없으며 어떤 전처리 과정이 실행되었는지도 확인할 수 없습니다. 스캔한 송장에 기울어짐, 그림자 또는 낮은 대비가 있는 경우 Mindee는 낮은 신뢰도 점수를 반환하며, 제출 전에 스캔 품질을 개선할 수 있는 방법이 없습니다.IronOCR전처리 파이프라인을 명시적으로 보여주므로, 문서 인식 실행 전에 특정 문서에 필요한 수정 사항을 정확하게 적용할 수 있습니다.

돌봄 제공자 접근 방식:

using Mindee;
using Mindee.Input;
using Mindee.Product.Invoice;

public class MindeeScanProcessor
{
    private readonly MindeeClient _client;

    public MindeeScanProcessor(string apiKey)
    {
        _client = new MindeeClient(apiKey);
    }

    public async Task<ScanResult> ProcessScannedInvoiceAsync(string scanPath)
    {
        // 민디 applies internal normalization — no developer control over preprocessing
        var inputSource = new LocalInputSource(scanPath);
        var response    = await _client.ParseAsync<InvoiceV4>(inputSource);
        var prediction  = response.Document.Inference.Prediction;

        return new ScanResult
        {
            InvoiceNumber = prediction.InvoiceNumber?.Value,
            Total         = prediction.TotalAmount?.Value,
            // Per-field confidence: only proxy for scan quality
            InvoiceNumberConfidence = prediction.InvoiceNumber?.Confidence,
            TotalConfidence         = prediction.TotalAmount?.Confidence
        };
    }
}
C#

IronOCR 접근 방식:

using IronOcr;
using System.Text.RegularExpressions;

public class IronOcrScanProcessor
{
    private readonly IronTesseract _ocr = new IronTesseract();

    public ScanResult ProcessScannedInvoice(string scanPath)
    {
        // First pass: read without preprocessing
        var quickResult = _ocr.Read(scanPath);

        OcrResult result;

        if (quickResult.Confidence < 75)
        {
            // Low confidence — apply full preprocessing pipeline
            using var input = new OcrInput();
            input.LoadImage(scanPath);
            input.Deskew();       // correct page rotation up to ±45 degrees
            input.DeNoise();      // remove scanner artifacts and speckle
            input.Contrast();     // normalize contrast for faded or overexposed scans
            input.Sharpen();      // sharpen blurred text edges

            result = _ocr.Read(input);
        }
        else
        {
            result = quickResult;
        }

        var invoiceNumber = Regex.Match(
            result.Text,
            @"Invoice\s*(?:Number|#|No\.?)?\s*:?\s*([A-Z0-9\-]+)",
            RegexOptions.IgnoreCase).Groups[1].Value;

        var total = Regex.Match(
            result.Text,
            @"(?:Total|Amount\s+Due)\s*:?\s*\$?([\d,]+\.\d{2})",
            RegexOptions.IgnoreCase).Groups[1].Value;

        return new ScanResult
        {
            InvoiceNumber    = invoiceNumber,
            Total            = total,
            DocumentConfidence = result.Confidence,
            PreprocessingApplied = quickResult.Confidence < 75
        };
    }
}

public class ScanResult
{
    public string InvoiceNumber        { get; set; }
    public string Total                { get; set; }
    public double DocumentConfidence   { get; set; }
    public bool   PreprocessingApplied { get; set; }
}
C#

먼저 빠르게 읽고 신뢰도가 낮은 데이터에 대해 전처리하는 2단계 패턴은 깨끗한 데이터에 대해 전체 전처리를 수행하는 데 드는 오버헤드를 방지합니다. 가장 일반적인 스캔 품질 시나리오 (약간 기울어진 평판 스캔, 팩스 아티팩트, 복사된 송장)에서는 Deskew()DeNoise()이(가) 대부분의 인식 정확도를 복구합니다. 이미지 품질 보정 가이드 에는 사용 가능한 모든 필터에 대한 설명과 다양한 스캔 결함에 가장 적합한 필터 조합에 대한 지침이 포함되어 있습니다. 이미지 방향 보정 가이드는 거꾸로 스캔한 문서의 자동 회전 기능을 다룹니다.

재무 문서 검색 가능한 PDF 아카이빙

Mindee는 PDF 출력물을 생성하지 않습니다. 이 시스템의 아키텍처는 입력 전용입니다. 문서를 제출하면 JSON 필드를 수신합니다. 스캔한 송장을 검색 가능한 형식으로 보관하는 팀은 Mindee의 추출 기능과 별도로 해당 파이프라인을 관리해야 합니다.IronOCR필드 추출에 사용된 동일한 인식 과정을 통해 검색 가능한 PDF를 직접 생성합니다. 추가 라이브러리나 두 번째 처리 단계가 필요하지 않습니다.

돌봄 제공자 접근 방식:

using Mindee;
using Mindee.Input;
using Mindee.Product.Invoice;

public class MindeeArchiveProcessor
{
    private readonly MindeeClient _client;

    public MindeeArchiveProcessor(string apiKey)
    {
        _client = new MindeeClient(apiKey);
    }

    public async Task ArchiveInvoiceAsync(string scanPath, string archivePath)
    {
        // Extract fields via 민디 (document transmitted to cloud)
        var inputSource = new LocalInputSource(scanPath);
        var response    = await _client.ParseAsync<InvoiceV4>(inputSource);
        var prediction  = response.Document.Inference.Prediction;

        // 민디 returns no PDF output — searchable PDF requires a separate library
        // (e.g., iTextSharp, PdfSharp, or a separate OCR library)
        // The scan at scanPath is the only PDF available for archiving;
        // it remains image-only with no embedded text layer
        Console.WriteLine($"Fields extracted. Searchable PDF: not available from Mindee.");
        Console.WriteLine($"Invoice: {prediction.InvoiceNumber?.Value}");
    }
}
C#

IronOCR 접근 방식:

using IronOcr;
using System.Text.RegularExpressions;

public class IronOcrArchiveProcessor
{
    private readonly IronTesseract _ocr = new IronTesseract();

    public ArchiveResult ArchiveInvoice(string scanPath, string archiveOutputPath)
    {
        // Apply preprocessing before recognition and archiving
        using var input = new OcrInput();
        input.LoadPdf(scanPath);   // works with both PDF scans and image files
        input.Deskew();
        input.DeNoise();

        var result = _ocr.Read(input);

        // Extract fields from the same recognition pass
        var invoiceNumber = Regex.Match(
            result.Text,
            @"Invoice\s*#?\s*:?\s*([A-Z0-9\-]+)",
            RegexOptions.IgnoreCase).Groups[1].Value;

        var vendor = result.Pages.FirstOrDefault()?.Lines
            .FirstOrDefault(l => l.Text.Trim().Length > 4)
            ?.Text.Trim();

        var totalMatch = Regex.Match(
            result.Text,
            @"Total\s*(?:Due)?\s*:?\s*\$?([\d,]+\.\d{2})",
            RegexOptions.IgnoreCase);

        // Write searchable PDF to archive in one call — no separate library needed
        result.SaveAsSearchablePdf(archiveOutputPath);

        return new ArchiveResult
        {
            InvoiceNumber    = invoiceNumber,
            VendorName       = vendor,
            Total            = totalMatch.Success ? totalMatch.Groups[1].Value : null,
            ArchivePath      = archiveOutputPath,
            DocumentConfidence = result.Confidence,
            PageCount        = result.Pages.Count()
        };
    }
}

public class ArchiveResult
{
    public string InvoiceNumber      { get; set; }
    public string VendorName         { get; set; }
    public string Total              { get; set; }
    public string ArchivePath        { get; set; }
    public double DocumentConfidence { get; set; }
    public int    PageCount          { get; set; }
}
C#

result.SaveAsSearchablePdf() 은(는) 인식된 텍스트 레이어를 직접 출력 PDF에 내장하여, 모든 PDF 뷰어나 Enterprise 콘텐츠 관리 시스템에서 선택 가능하고 검색 가능한 파일을 생성합니다. 필드 추출과 아카이브가 동일한 패스로 실행되며, 하나의 _ocr.Read(input) 호출이 패턴 매칭을 위한 result.Text 및 아카이브를 위한 result.SaveAsSearchablePdf() 모두 제공합니다. 검색 가능한 PDF 가이드는 HOCR 내보내기 및 PDF OCR 사용 사례 페이지를 포함한 출력 옵션을 다루며 문서 아카이브 파이프라인을 위한 생산 배포 패턴을 다룹니다.

FinancialDocumentV1 사용자 지정 엔드포인트 제거

Mindee의 FinancialDocumentV1 API는 문서 유형을 자동 감지하여 송장과 영수증 모두를 처리합니다. 이 기능을 사용하는 팀은 분기 논리를 제거할 수 있지만 클라우드 의존도가 높아집니다. 문서 유형에 관계없이 모든 문서가 업로드되기 때문입니다.IronOCR로 교체하면 단어 수준의 위치 데이터를 사용하여 클라우드 호출 없이 문서 구조와 추출 로직을 감지할 수 있습니다.

돌봄 제공자 접근 방식:

using Mindee;
using Mindee.Input;
using Mindee.Product.FinancialDocument;

public class MindeeFinancialRouter
{
    private readonly MindeeClient _client;

    public MindeeFinancialRouter(string apiKey)
    {
        _client = new MindeeClient(apiKey);
    }

    public async Task<FinancialSummary> ProcessFinancialDocumentAsync(string filePath)
    {
        // All financial documents uploaded for auto-detection and parsing
        var inputSource = new LocalInputSource(filePath);
        var response    = await _client.ParseAsync<FinancialDocumentV1>(inputSource);
        var prediction  = response.Document.Inference.Prediction;

        return new FinancialSummary
        {
            DocumentType  = prediction.DocumentType?.Value,  // "INVOICE" or "RECEIPT"
            InvoiceNumber = prediction.InvoiceNumber?.Value,
            Date          = prediction.Date?.Value?.ToString(),
            TotalAmount   = prediction.TotalAmount?.Value,
            SupplierName  = prediction.SupplierName?.Value,
            CustomerName  = prediction.CustomerName?.Value
        };
    }
}
C#

IronOCR 접근 방식:

using IronOcr;
using System.Text.RegularExpressions;

public class IronOcrFinancialRouter
{
    private readonly IronTesseract _ocr = new IronTesseract();

    public FinancialSummary ProcessFinancialDocument(string filePath)
    {
        var result = _ocr.Read(filePath);
        var text   = result.Text;

        // Detect document type using structural keywords from word data
        var isInvoice = DetectInvoice(result);

        if (isInvoice)
        {
            return new FinancialSummary
            {
                DocumentType  = "INVOICE",
                InvoiceNumber = Regex.Match(text,
                    @"Invoice\s*#?\s*:?\s*([A-Z0-9\-]+)",
                    RegexOptions.IgnoreCase).Groups[1].Value,
                Date          = Regex.Match(text,
                    @"(?:Invoice\s+)?Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})",
                    RegexOptions.IgnoreCase).Groups[1].Value,
                TotalAmount   = ParseAmount(text,
                    @"Total\s*(?:Due|Amount)?\s*:?\s*\$?([\d,]+\.\d{2})"),
                SupplierName  = ExtractTopLine(result),
                CustomerName  = Regex.Match(text,
                    @"Bill\s+To\s*:?\s*\n?(.+)",
                    RegexOptions.IgnoreCase).Groups[1].Value.Trim()
            };
        }
        else
        {
            // Receipt structure: merchant at top, no "Bill To" section
            return new FinancialSummary
            {
                DocumentType = "RECEIPT",
                Date         = Regex.Match(text,
                    @"\b(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})\b").Value,
                TotalAmount  = ParseAmount(text,
                    @"(?:Total|Amount\s+Due|Grand\s+Total)\s*:?\s*\$?([\d,]+\.\d{2})"),
                SupplierName = ExtractTopLine(result)
            };
        }
    }

    private bool DetectInvoice(OcrResult result)
    {
        // Invoice indicators: "Invoice", "Bill To", "Due Date", line items with quantities
        var text = result.Text;
        var invoiceSignals = new[] { "Invoice", "Bill To", "Due Date", "Purchase Order" };
        return invoiceSignals.Any(s =>
            text.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0);
    }

    private string ExtractTopLine(OcrResult result)
    {
        return result.Pages
            .FirstOrDefault()
            ?.Lines
            .FirstOrDefault(l => l.Text.Trim().Length > 4)
            ?.Text.Trim();
    }

    private decimal? ParseAmount(string text, string pattern)
    {
        var match = Regex.Match(text, pattern, RegexOptions.IgnoreCase);
        if (match.Success &&
            decimal.TryParse(match.Groups[1].Value.Replace(",", ""), out var val))
            return val;
        return null;
    }
}

public class FinancialSummary
{
    public string   DocumentType  { get; set; }
    public string   InvoiceNumber { get; set; }
    public string   Date          { get; set; }
    public decimal? TotalAmount   { get; set; }
    public string   SupplierName  { get; set; }
    public string   CustomerName  { get; set; }
}
C#

문서 유형 감지 로직은 Mindee의 서버 측 DocumentType 필드를 result.Text에 대한 단순 키워드 스캔으로 대체합니다. 대부분의 재무 문서에서 "송장" 또는 "청구 대상"이라는 문구는 송장을 명확하게 식별하는 데 사용됩니다. 부재는 영수증을 식별합니다. result.Pages의 워드레벨 위치 데이터는 문서 세트에 엣지 케이스가 포함된 경우 더 정교한 레이아웃 기반 감지를 가능하게 합니다. 결과 읽기 가이드Words, Lines, Paragraphs 및 그들의 경계 좌표를 포함한 전체 객체 모델을 설명합니다.

민디 API와IronOCR매핑 참조

민디IronOCR에 상응하는
new MindeeClient(apiKey)new IronTesseract() - API 키 불필요
new LocalInputSource(filePath)new OcrInput() + input.LoadImage(filePath) 또는 ocr.Read(filePath)
_client.ParseAsync<InvoiceV4>(input)_ocr.Read(filePath) + result.Text 에서의 정규식 추출
_client.ParseAsync<ReceiptV5>(input)_ocr.Read(filePath) + 영수증 추출 패턴
_client.ParseAsync<PassportV1>(input)_ocr.Read(filePath) + CropRectangle 을 통한 MRZ 영역 추출
_client.ParseAsync<FinancialDocumentV1>(input)_ocr.Read(filePath) + result.Text 에 대한 문서 유형 감지
response.Document.Inference.Predictionresult.Text, result.Pages, result.Lines, result.Words
prediction.InvoiceNumber?.ValueRegex.Match(result.Text, @"Invoice\s*#?\s*:?\s*([A-Z0-9\-]+)")
prediction.SupplierName?.Value첫 페이지 위쪽 라인 result.Pages[0].Lines.First() 통해
prediction.TotalAmount?.ValueRegex.Match(result.Text, @"Total\s*:?\s*\$?([\d,]+\.\d{2})")
prediction.LineItemsresult.Lines 줄 아이템 정규식 패턴 필터링
prediction.SupplierPaymentDetails[].IbanRegex.Match(result.Text, @"IBAN\s*:?\s*([\w\s]+)")
prediction.InvoiceDate?.ValueRegex.Match(result.Text, @"Date\s*:?\s*(\d{1,2}[/-]\d{1,2}[/-]\d{4})")
field.Confidenceresult.Confidence (문서 레벨) 또는 word.Confidence (단어별)
catch (MindeeException ex)동등한 항목 없음 — 인식 시점에 네트워크 오류 없음
await Task.Delay(100) (속도 제한)필수 사항 아님 - 요금 제한 없음
input.LoadPdf(path)ocrInput.LoadPdf(path) - 동일한 작업, 완전 로컬
구성의 API 키IronOcr.License.LicenseKey = "..." 을 통한 라이선스 키 - 회전 불필요

일반적인 마이그레이션 문제와 해결책

문제 1: 자르기 사각형 좌표가 문서 레이아웃과 일치하지 않음

Mindee: 공간 필드 좌표는 서버 측에서 처리됩니다. 민디 모델은 개발자의 좌표 설정 없이도 다양한 송장 레이아웃에 맞춰 조정됩니다.

해결 방법: 공급업체 문서 세트에서 추출한 대표 샘플을 기준으로 영역 좌표를 측정합니다. 아무 이미지 편집기에서 샘플 송장을 열고, 픽셀 크기를 읽고, CropRectangle(x, y, width, height) 을 정의합니다. 레이아웃이 가변적인 송장의 경우, 먼저 전체 문서를 읽고 단어 위치 데이터를 사용하여 영역을 동적으로 찾으세요.

var result  = _ocr.Read("invoice.jpg");
var allWords = result.Pages.First().Words;

// Find the word "Total" and read the region 50px to its right
var totalLabel = allWords.FirstOrDefault(w =>
    w.Text.Equals("Total", StringComparison.OrdinalIgnoreCase));

if (totalLabel != null)
{
    var valueRegion = new CropRectangle(
        totalLabel.X + totalLabel.Width + 5,
        totalLabel.Y - 5,
        200,
        totalLabel.Height + 10);

    using var valueInput = new OcrInput();
    valueInput.LoadImage("invoice.jpg", valueRegion);
    var valueResult = _ocr.Read(valueInput);
    Console.WriteLine($"Total: {valueResult.Text.Trim()}");
}
C#

영역 기반 OCR 예시는 이러한 동적 영역 패턴을 완벽하게 작동하는 예시로 보여줍니다.

문제 2: Mindee를 제거한 후 비동기 호출 사이트가 작동하지 않음

민디(Mindee): 민디 API의 전체 표면은 네트워크 I/O를 사용하기 때문에 비동기식으로 작동합니다. await _client.ParseAsync<t>() 을(를) 기반으로 구축된 컨트롤러와 서비스 메서드는 호출 체인 전반에 비동기입니다.

솔루션: IronOCR의 Read() 메서드는 동기식입니다. 기존의 비동기 호출 사이트는 Task.Run으로 동기 호출을 래핑하여 즉시 작동합니다.

// Existing async signature preserved for callers
public async Task<string> ExtractInvoiceNumberAsync(string filePath)
{
    return await Task.Run(() =>
    {
        var result = new IronTesseract().Read(filePath);
        return Regex.Match(result.Text,
            @"Invoice\s*#?\s*:?\s*([A-Z0-9\-]+)",
            RegexOptions.IgnoreCase).Groups[1].Value;
    });
}
C#

고속 처리 ASP.NET 시나리오의 경우, Task.Run 래퍼와 네이티브 비동기 경로 중에서 결정하기 전에 비동기 OCR 가이드를 검토하세요.

문제 3: 저품질 스캔에서 추출 정확도가 떨어짐

민디(Mindee): 민디의 전처리 과정은 내부적으로 자동으로 이루어집니다. 스캔 품질 문제로 인해 현장 신뢰도 점수가 낮아지며, 재제출 전에 개발자의 개입이 불가능합니다.

해결 방법: 인식 전에 IronOCR의 전처리 파이프라인을 적용합니다. Deskew()DeNoise() 의 조합은 계정 지급 워크플로에서 일반적으로 볼 수 있는 평판 스캔 결함에 대해 대부분의 정확도를 복구합니다.

using var input = new OcrInput();
input.LoadImage("faded-invoice.jpg");
input.Deskew();
input.DeNoise();
input.Contrast();    // for faded or low-contrast thermal paper receipts
input.Binarize();    // convert to clean black-and-white before recognition
var result = new IronTesseract().Read(input);
C#

심하게 열악한 스캔의 경우, input.DeepCleanBackgroundNoise() 은(는) 보다 강력한 배경 제거 패스를 적용합니다. 이미지 품질 보정 가이드에는 임계값이 명시되어 있으며, 필터 마법사는 주어진 문서 샘플에서 정확도를 향상시키는 필터를 식별하는 데 도움을 줍니다.

문제 4: API 키 및 네트워크 송신 구성이 제거되었습니다.

Mindee: 앱 설정에 저장된 API 키, api.mindee.net으로의 아웃바운드 HTTPS를 허용하는 네트워크 출구 규칙, 및 HttpRequestException을 래핑하는 재시도 로직은 모두 필요한 인프라입니다.

해결 방법: 세 가지를 모두 함께 제거합니다. 민디 API 키 항목이 설정에서 삭제되었습니다. 네트워크 송신 규칙이 취소되었습니다. try/catch (HttpRequestException) 블록이 제거됩니다. 남은 유일한 자격 증명은 시작 시 한 번 설정되는IronOCR라이선스 키입니다.

// appsettings.json: remove "Mindee:ApiKey"
// Firewall: revoke egress rule for api.mindee.net
// Startup.cs or Program.cs:
IronOcr.License.LicenseKey = Configuration["IronOcr:LicenseKey"];
// 아니요 rotation schedule, no secure storage beyond standard config secret management
C#

제5호: 다중 페이지 PDF 페이지 수 청구

Mindee: Mindee에 업로드된 12페이지 공급업체 명세서는 월별 할당량에 비해 12페이지를 소비합니다. 프로 등급 초과 사용 요금의 경우, 월 사용량 한도에 근접했을 때 해당 문서 하나당 월 1.20달러의 추가 비용이 발생합니다.

**해결책:**IronOCR페이지당 비용 없이 여러 페이지로 구성된 PDF 파일을 처리합니다. 전체 문서를 불러온 후 페이지를 순차적으로 처리하세요.

using var input = new OcrInput();
input.LoadPdf("vendor-statement.pdf");   // 12 pages — no billing unit increment
var result = new IronTesseract().Read(input);

foreach (var page in result.Pages)
    Console.WriteLine($"Page {page.PageNumber}: {page.Text.Length} characters recognized");
C#

문제 6: FinancialDocumentV1 종속성을 단일 패턴으로 대체할 수 없습니다.

Mindee: FinancialDocumentV1이(가) 문서 유형을 자동 감지하고 문서 유형에 대한 호출 코드 가지 분기 없이 필드를 추출합니다.

해결책: 키워드 존재 여부를 이용하여 경량화된 탐지기를 구축합니다. 재무 문서는 "송장", "청구 대상" 또는 "만기일"이 포함된 송장과 "영수증", "감사합니다"가 포함되거나 송장 표시가 없는 영수증으로 명확하게 구분됩니다. 두 가지 추출 방법 Plus 세 줄짜리 탐지기가 민디 API 호출을 대체하여, 형식이 올바른 문서에 대한 정확도를 저하시키지 않습니다.

var result  = _ocr.Read(filePath);
var summary = result.Text.IndexOf("Invoice", StringComparison.OrdinalIgnoreCase) >= 0
    ? ExtractInvoiceFields(result)
    : ExtractReceiptFields(result);
C#

민디 이주 체크리스트

사전 마이그레이션

코드베이스 전체에서 민디 사용 내역을 모두 감사합니다.

grep -r "using Mindee" --include="*.cs" .
grep -r "MindeeClient\|ParseAsync\|InvoiceV4\|ReceiptV5\|PassportV1\|FinancialDocumentV1" --include="*.cs" .
grep -r "LocalInputSource\|MindeeException" --include="*.cs" .
grep -r "Mindee:ApiKey\|mindee_api_key\|MINDEE_API_KEY" --include="*.json" --include="*.env" --include="*.yml" .
SHELL

재고 조사 결과:

  • ParseAsync<t>을(를) 사용하여 고유 호출 사이트 수를 세십시오
  • 어떤 문서 유형이 사용되는지 확인 (InvoiceV4, ReceiptV5, PassportV1, FinancialDocumentV1)
  • 민디 호출에서 전파되는 모든 비동기 메서드 체인을 식별합니다.
  • 구성 파일 및 비밀 저장소에서 API 키 참조를 찾습니다.
  • 민디 네트워크 호출을 감싸는 재시도 로직을 식별합니다.
  • 민디 엔드포인트로의 아웃바운드 트래픽을 허용하는 네트워크 송신 규칙을 식별합니다.

코드 마이그레이션

  1. 프로젝트 파일에서 Mindee NuGet 패키지를 제거합니다
  2. IronOCR을 설치하기 위해 dotnet add package IronOcr을(를) 실행합니다
  3. 애플리케이션 시작에 IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"을 추가합니다
  4. 모든 using Mindee, using Mindee.Inputusing Mindee.Product.* 지시어를 제거합니다
  5. MindeeClient 생성자 주입을 IronTesseract 인스턴스화 또는 DI 등록으로 대체합니다
  6. ParseAsync<InvoiceV4> 호출을 _ocr.Read(filePath) 및 송장 추출 메서드로 교체합니다
  7. ParseAsync<ReceiptV5> 호출을 _ocr.Read(filePath) 및 영수증 추출 메서드로 교체합니다
  8. ParseAsync<PassportV1> 호출을 CropRectangle을 사용한 영역 기반 OCR로 교체합니다
  9. ParseAsync<FinancialDocumentV1> 호출을 문서 유형 감지기 + 라우팅 패턴으로 교체합니다
  10. 모든 await Task.Delay(...) 속도 제한 준수 라인을 제거합니다
  11. OCR 경로에서 모든 catch (MindeeException)catch (HttpRequestException) 블록을 제거합니다
  12. OcrInput 전처리 호출을 추가합니다 (Deskew, DeNoise, Contrast) 스캔 문서 경로에 대해
  13. 문서 아카이브 경로에 result.SaveAsSearchablePdf(archivePath)을 추가합니다
  14. 모든 설정 파일과 비밀 저장소에서 민디 API 키를 제거합니다.
  15. 네트워크 모킹 없이 동기적으로 실행되도록 통합 테스트를 업데이트합니다.

마이그레이션 이후

  • 각 문서 유형을 포괄하는 20~30개의 문서 샘플 세트를 사용하여 추출 정확도를 검증합니다.
  • 대표적인 깨끗한 스캔에서의 result.Confidence 값이 80 이상임을 확인합니다; 다음과 같은 경우 전처리를 적용하세요
  • 비뚤어진 및 열화된 스캔 샘플에서의 전처리 파이프라인 (Deskew, DeNoise)을 테스트합니다
  • 다중 페이지 PDFs가 올바른 result.Pages.Count을 생성하고 페이지별 콘텐츠를 제공하는지 확인합니다
  • result.SaveAsSearchablePdf() 출력이 Adobe Acrobat 및 시스템 PDF 뷰어에서 검색 가능한 것인지 확인합니다
  • 공급업체 세트의 문서 레이아웃 변형에 대한 모든 영역 기반 추출 (CropRectangle)을 테스트합니다
  • Task.Delay 호출 없이 배치 처리를 실행하고 스레딩 문제 없음을 확인합니다
  • 인터넷 연결이 없는 상태에서 애플리케이션이 정상적으로 시작되고 실행되는지 확인하십시오.
  • 각 진입점에서 첫 번째 _ocr.Read() 호출 전에 라이선스 키 초기화가 실행되는지 확인합니다
  • 구성, 환경 변수 또는 비밀 키에 민디 API 키 참조가 남아 있지 않은지 확인하십시오.

##IronOCR로 마이그레이션할 때의 주요 이점

금융 문서에 대한 완벽한 데이터 주권을 확보하세요. 마이그레이션 후, 공급업체 IBAN 코드, 라우팅 번호, 고객 EIN 및 상세 내역은 귀사 인프라 외부로 유출되지 않습니다. 규정 준수 범위는 귀사 조직에만 적용됩니다. 타사 AI 공급업체와의 프로세서 계약은 감사 추적에서 삭제됩니다. GLBA, CMMC, FedRAMP 또는 데이터 상주 요건을 준수하는 팀은 외부 클라우드 전송에 필요한 규정 준수 검토 없이도 재무 문서를 처리할 수 있습니다.

사람이 볼륨과 관계없이 일정한 비용. $999에서IronOCR Lite 라이선스는 무제한 문서 처리가 가능한 개발자 한 명을 포함합니다. 월 500건에서 50,000건으로 송장 발행량을 늘리는 데 추가 비용은 전혀 들지 않습니다. 연말 처리량 급증, 일괄 수정 실행 및 개발 테스트 주기는 청구 카운터를 증가시키지 않습니다. 한 달에 5,000페이지를 처리하는 팀의 3년 총 소유 비용은 민디 Pro의 경우 약 17,964달러에서IronOCR영구 라이선스의 경우 1,499~2,999달러로 감소합니다. 자세한 등급 정보는 IronOCR 제품 페이지를 참조하세요.

**추출 로직을 영구적으로 소유하세요.**IronOCR추출 패턴은 저장소에 있는 일반 C# 코드입니다. 이러한 코드는 외부 공급업체의 출시 일정이나 API 버전 관리 결정과 관계없이 버전 관리, 검토, 테스트 및 배포가 가능합니다. Mindee가 InvoiceV5을 출시하고 InvoiceV4을 더 이상 사용하지 않게 될 때, 공급업체에 의해 이주 기한이 부과됩니다. 추출 패턴을 유지할 때, 개선은 git commit입니다.

실제 스캔 품질을 위한 전처리 제어. 회계 부서는 수십 또는 수백 개의 공급업체로부터 송장을 받는데, 각 송장은 서로 다른 장비와 설정으로 스캔됩니다. IronOCR의 전처리 파이프라인 — Deskew(), DeNoise(), Contrast(), Sharpen(), Binarize() — 은 각 스캔 범주의 특정 결함을 해결합니다. 감열식 영수증 사진은 평판 스캐너로 스캔한 여러 페이지짜리 청구서와는 다른 결함이 있습니다. 따라서 각 경로에 맞는 필터를 적용해야 합니다. Mindee의 전처리 과정은 보이지 않으며 구성할 수도 없습니다. 전체 필터 목록은 전처리 기능 페이지를 참조하십시오.

단계 하나로 검색 가능한 PDF 아카이브. IronOCR을 통해 처리된 모든 송장은 result.SaveAsSearchablePdf()을 사용하여 검색 가능한 PDF로 아카이브될 수 있습니다. 인식된 텍스트 레이어가 출력 파일에 포함되어 문서 관리 시스템, SharePoint 라이브러리 및 Enterprise 콘텐츠 저장소에서 모든 단어를 전체 텍스트로 검색할 수 있습니다. Mindee는 PDF 출력 기능을 전혀 제공하지 않습니다. 이전에는 검색 가능한 아카이빙을 위해 별도의 라이브러리, 별도의 처리 과정, 그리고 추가적인 유지 관리가 필요했습니다. 마이그레이션 후, 추출 및 아카이브는 하나의 _ocr.Read(input) 호출로 축소됩니다.

**아키텍처 변경 없이 모든 곳에 배포 가능.**IronOCR동일한 NuGet 패키지와 초기화를 사용하여 Windows, Linux, macOS, Docker, Azure App Service, AWS Lambda 및 Google Cloud Run에 배포할 수 있습니다. 밀폐된 환경, 공장 현장 시스템, 정부 보안 시설 모두 수정 없이 작동합니다. Docker 배포 가이드 , Azure 가이드AWS 가이드는 각 플랫폼에 대한 환경별 구성을 다룹니다.

참고해 주세요: Adobe Acrobat, Mindee, PDFSharp, Tesseract, 및 iText는 각각 소유자의 등록 상표입니다. 이 사이트는 Adobe Inc., Google, Mindee, empira Software GmbH 또는 iText Group과 제휴, 지지 또는 후원을 받지 않았습니다. 모든 제품 이름, 로고 및 브랜드는 각각 소유자의 자산입니다. 비교는 정보 제공 목적으로만 사용되며, 작성 시점에 공개적으로 이용 가능한 정보를 반영합니다.

관련 기사

Key in blue circle

무료 30일 체험 키를 즉시 받으세요.

Your trial license will be sent to your email address

제한 없음. 100% 무제한 이용. 신용카드 불필요.

bullet_checked신용카드나 계정 생성은 필요하지 않습니다.제한 없음. 100% 무제한 이용. 신용카드 불필요.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
부담 없는 무료 상담을 받아보세요
아래 양식을 작성하시거나 sales@ironsoftware.com으로 이메일을 보내주세요.
고객님의 정보는 항상 비밀로 유지됩니다.
전 세계 수백만 엔지니어들이 신뢰하는 제품입니다.
Iron Software의 고객 로고
지금 바로 30일 무료 체험판 키를 받으세요.
신용카드나 계정 생성은 필요하지 않습니다.