C#에서 검색 가능한 PDF로 결과를 저장하는 방법

IronOCR을 사용하여 C#에서 검색 가능한 PDF를 저장하세요

This article was translated from English: Does it need improvement?
Translated
View the article in English

IronOCR은 C# 개발자가 OCR 기술을 사용하여 스캔한 문서와 이미지를 검색 가능한 PDF로 변환할 수 있도록 지원하며, 단 몇 줄의 코드로 파일, 바이트 또는 스트림 형식으로 출력을 지원합니다.

검색 가능한 PDF는 흔히 OCR(광학 문자 인식) PDF라고도 하며, 스캔한 이미지와 기계가 읽을 수 있는 텍스트가 모두 포함된 PDF 문서 유형입니다. 이러한 PDF 파일은 스캔한 종이 문서나 이미지에 OCR(광학 문자 인식)을 수행하여 이미지 속 텍스트를 인식하고 선택 및 검색 가능한 텍스트로 변환함으로써 생성됩니다.

SaveAsSearchablePdfReadPhoto, ReadScreenShotReadDocumentAdvanced의 결과에서도 사용할 수 있어, 사진 및 고급 문서 OCR 워크플로를 통해 검색 가능한 PDF를 생성할 수 있습니다. 이 기능은 종이 문서를 디지털화하거나 기존 PDF 파일을 검색 가능하게 만들어 문서 관리를 개선할 때 특히 유용합니다.

빠른 시작: 한 줄로 검색 가능한 PDF 내보내기

RenderSearchablePdf = true을 설정하고, 입력값에 Read(...)을 실행한 다음, SaveAsSearchablePdf(...)을 호출하십시오. IronOCR을 사용하여 검색 기능이 완벽하게 지원되는 PDF를 생성하는 방법은 이것뿐입니다.

  1. NuGet 패키지 관리자를 사용하여 https://www.nuget.org/packages/IronOcr 설치하기

    PM > Install-Package IronOcr
  2. 다음 코드 조각을 복사하여 실행하세요.

    new IronOcr.IronTesseract { Configuration = { RenderSearchablePdf = true } } .Read(new IronOcr.OcrImageInput("file.jpg")).SaveAsSearchablePdf("searchable.pdf");
  3. 실제 운영 환경에서 테스트할 수 있도록 배포하세요.

    무료 체험판으로 오늘 프로젝트에서 IronOCR 사용 시작하기

    arrow pointer


OCR 결과를 검색 가능한 PDF 파일로 내보내는 방법은 무엇인가요?

IronOCR을 사용하여 결과를 검색 가능한 PDF로 내보내려면, Configuration.RenderSearchablePdf 속성을 true로 설정하고, Read 메서드에서 OCR 결과 객체를 가져온 다음, 출력 파일 경로를 지정하여 SaveAsSearchablePdf를 호출하십시오.

입력

해리 포터 소설의 한 페이지로, TIFF 파일로 스캔되어 OcrImageInput를 통해 불러온 것입니다. 이 페이지에는 텍스트가 빽빽하게 인쇄되어 있어, 검색 가능한 PDF 텍스트 레이어를 테스트하기에 적합한 실제적인 입력 자료입니다.

해리 포터 책의 8장 '죽음의 날 파티' 페이지로, 해리가 거의 목 없는 닉을 만나는 내용이 담긴 텍스트

potter.tiff: 보이지 않는 텍스트 레이어가 포함된 검색 가능한 PDF를 생성하기 위한 OCR 입력 자료로 사용된 스캔된 소설 페이지.

:path=/static-assets/ocr/content-code-examples/how-to/searchable-pdf-searchable-pdf.cs
using IronOcr;

// Instantiate IronTesseract
IronTesseract ocrTesseract = new IronTesseract();

// Enable render as searchable PDF
ocrTesseract.Configuration.RenderSearchablePdf = true;

// Add image
using var imageInput = new OcrImageInput("Potter.tiff");
// Perform OCR
OcrResult ocrResult = ocrTesseract.Read(imageInput);

// Export as searchable PDF
ocrResult.SaveAsSearchablePdf("searchablePdf.pdf");
Imports IronOcr

' Instantiate IronTesseract
Private ocrTesseract As New IronTesseract()

' Enable render as searchable PDF
ocrTesseract.Configuration.RenderSearchablePdf = True

' Add image
Dim imageInput = New OcrImageInput("Potter.tiff")
' Perform OCR
Dim ocrResult As OcrResult = ocrTesseract.Read(imageInput)

' Export as searchable PDF
ocrResult.SaveAsSearchablePdf("searchablePdf.pdf")
$vbLabelText   $csharpLabel

산출

searchablePdf.pdf: 검색 가능한 PDF 출력물입니다. 단어를 선택하거나 검색하여 OCR 텍스트 레이어를 확인해 보세요.

생성된 PDF 파일에는 원본 스캔 페이지 이미지가 포함되며, 인식된 각 단어 위에 보이지 않는 텍스트 레이어가 배치됩니다. 뷰어에서 WORD를 선택하거나 검색하여 텍스트 레이어가 있는지 확인하십시오.

IronOCR은 오버레이에 특정 글꼴을 사용하므로, 원본과 비교했을 때 렌더링된 텍스트 크기에 약간의 차이가 발생할 수 있습니다.

다중 페이지 TIFF 파일이나 복잡한 문서를 처리할 때, IronOCR은 모든 페이지를 자동으로 처리하여 출력에 포함시킵니다. 이 라이브러리는 페이지 순서와 텍스트 오버레이 위치 지정을 자동으로 처리하여 텍스트와 이미지 간의 정확한 매핑을 보장합니다.

사진이나 고급 문서 스캔 파일을 검색 가능한 PDF로 만드는 방법은 무엇인가요?

ReadPhoto, ReadScreenShot 또는 ReadDocumentAdvanced을 사용할 경우 검색 가능한 PDF 내보내기 기능도 이용할 수 있습니다. 이 메서드들은 각각 SaveAsSearchablePdf를 지원하는 결과 유형을 반환합니다.

선택적으로 이러한 메서드를 호출할 때 ModelType을 전달할 수 있습니다. 기본값은 Normal이며, Enhanced는 속도 저하를 감수하고 더 높은 정확도를 제공합니다.

입력

LoadImage를 통해 로드된, 글씨가 그려진 벽화 사진. 이 문맥에는 실제 환경에 포함된 여러 WORD가 포함되어 있어, ReadPhoto 모델에 대한 실용적인 테스트가 됩니다.

ReadPhoto OCR의 입력으로 사용된 텍스트가 포함된 사진

photo.png: ReadPhoto의 Enhanced 모델을 통해 불러온 벽면 벽화 사진으로, 검색 가능한 PDF를 생성했습니다.

using IronOcr;

var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("photo.png");

// ReadPhoto with Enhanced model
OcrPhotoResult photoResult = ocr.ReadPhoto(input, ModelType.Enhanced);
Console.WriteLine(photoResult.Text);

// Save as searchable PDF
byte[] pdfBytes = photoResult.SaveAsSearchablePdf();
File.WriteAllBytes("searchable-photo.pdf", pdfBytes);
using IronOcr;

var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("photo.png");

// ReadPhoto with Enhanced model
OcrPhotoResult photoResult = ocr.ReadPhoto(input, ModelType.Enhanced);
Console.WriteLine(photoResult.Text);

// Save as searchable PDF
byte[] pdfBytes = photoResult.SaveAsSearchablePdf();
File.WriteAllBytes("searchable-photo.pdf", pdfBytes);
Imports IronOcr

Dim ocr As New IronTesseract()
Using input As New OcrInput()
    input.LoadImage("photo.png")

    ' ReadPhoto with Enhanced model
    Dim photoResult As OcrPhotoResult = ocr.ReadPhoto(input, ModelType.Enhanced)
    Console.WriteLine(photoResult.Text)

    ' Save as searchable PDF
    Dim pdfBytes As Byte() = photoResult.SaveAsSearchablePdf()
    File.WriteAllBytes("searchable-photo.pdf", pdfBytes)
End Using
$vbLabelText   $csharpLabel

산출

searchable-photo.pdf: ReadPhoto에서 생성된 검색 가능한 PDF 파일입니다. 텍스트 레이어는 모든 PDF 뷰어에서 전체 텍스트 검색을 지원합니다.

생성된 검색 가능한 PDF 파일에는 인식된 단어 위에 보이지 않는 텍스트 레이어가 포함되어 있습니다. PDF 뷰어에서 "Milk"를 검색하면 원본 사진의 텍스트에서 직접 추출된 3개의 일치 항목이 반환됩니다.

ReadDocumentAdvanced에 대해서도 동일한 접근 방식을 적용하면 OcrDocAdvancedResult이 반환됩니다:

입력

LoadImage을 통해 로드된 스캔된 청구서. 이 데이터에는 ReadDocumentAdvanced 모델이 인식하여 검색 가능한 텍스트 레이어로 삽입하는 구조화된 필드(공급업체 이름, 항목, 합계)가 포함되어 있습니다.

ReadDocumentAdvanced OCR의 입력으로 사용된 송장 문서

invoice.png: OcrInput에 로드된 스캔된 청구서이며, Enhanced 모델을 사용하여 ReadDocumentAdvanced로 전달되었습니다.

using IronOcr;

var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("invoice.png");

// ReadDocumentAdvanced with Enhanced model
OcrDocAdvancedResult docResult = ocr.ReadDocumentAdvanced(input, ModelType.Enhanced);
byte[] docPdfBytes = docResult.SaveAsSearchablePdf();
File.WriteAllBytes("searchable-doc.pdf", docPdfBytes);
using IronOcr;

var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("invoice.png");

// ReadDocumentAdvanced with Enhanced model
OcrDocAdvancedResult docResult = ocr.ReadDocumentAdvanced(input, ModelType.Enhanced);
byte[] docPdfBytes = docResult.SaveAsSearchablePdf();
File.WriteAllBytes("searchable-doc.pdf", docPdfBytes);
Imports IronOcr

Dim ocr As New IronTesseract()
Using input As New OcrInput()
    input.LoadImage("invoice.png")

    ' ReadDocumentAdvanced with Enhanced model
    Dim docResult As OcrDocAdvancedResult = ocr.ReadDocumentAdvanced(input, ModelType.Enhanced)
    Dim docPdfBytes As Byte() = docResult.SaveAsSearchablePdf()
    File.WriteAllBytes("searchable-doc.pdf", docPdfBytes)
End Using
$vbLabelText   $csharpLabel

산출

searchable-doc.pdf: ReadDocumentAdvanced에서 생성된 검색 가능한 PDF 파일입니다. 송장 필드를 선택하고 검색할 수 있습니다.

SaveAsSearchablePdfReadPassport 또는 ReadLicensePlate 결과에 대해 지원되지 않으며, ExtensionAdvancedScanException. 예외를 발생시킵니다.

여러 페이지로 구성된 문서 작업하기

다중 페이지 문서에 대한 PDF OCR 작업을 처리할 때, IronOCR은 각 페이지를 순차적으로 처리하며 원본 문서의 구조를 유지합니다.

입력

OcrPdfInput를 통해 로드된 Hartwell Capital Management의 11페이지 분량 연례 보고서. 1~10페이지(인덱스 0~9)는 PageIndices 범위를 사용하여 선택되며, 단일 Read 호출로 처리됩니다.

multi-page-scan.pdf: 다중 페이지 검색 가능 PDF 변환의 입력 자료로 사용된 11페이지 분량의 Hartwell Capital Management 연차 보고서.

:path=/static-assets/ocr/content-code-examples/how-to/searchable-pdf-multi-page.cs
using IronOcr;

// Create the OCR engine. RenderSearchablePdf is false by default; no need to set it when using OcrPdfInput directly
var ocrTesseract = new IronTesseract();

// Load pages 1–10 (indices 0–9) only; PageIndices avoids loading and OCR-ing the full document unnecessarily
using var pdfInput = new OcrPdfInput("multi-page-scan.pdf", PageIndices: Enumerable.Range(0, 10));

// Run OCR across all selected pages in order
OcrResult result = ocrTesseract.Read(pdfInput);

// Write the searchable PDF; true = apply the input's image filters to the embedded page images in the output
result.SaveAsSearchablePdf("searchable-multi-page.pdf", true);
Imports IronOcr

' Create the OCR engine. RenderSearchablePdf is false by default; no need to set it when using OcrPdfInput directly
Dim ocrTesseract As New IronTesseract()

' Load pages 1–10 (indices 0–9) only; PageIndices avoids loading and OCR-ing the full document unnecessarily
Using pdfInput As New OcrPdfInput("multi-page-scan.pdf", PageIndices:=Enumerable.Range(0, 10))
    ' Run OCR across all selected pages in order
    Dim result As OcrResult = ocrTesseract.Read(pdfInput)

    ' Write the searchable PDF; true = apply the input's image filters to the embedded page images in the output
    result.SaveAsSearchablePdf("searchable-multi-page.pdf", True)
End Using
$vbLabelText   $csharpLabel

산출

searchable-multi-page.pdf: 10페이지 분량의 검색 가능한 PDF 출력물. 각 페이지에는 전체 텍스트 검색을 위한 보이지 않는 텍스트 레이어가 포함되어 있습니다.

결과 PDF 파일은 10페이지(원본 보고서의 1~10페이지)로 구성되며, 각 페이지에는 추출된 내용을 모든 PDF 뷰어에서 선택 및 검색할 수 있도록 하는 보이지 않는 텍스트 레이어가 포함되어 있습니다.

검색 가능한 PDF를 만들 때 필터를 적용하려면 어떻게 해야 하나요?

SaveAsSearchablePdf 두 번째 매개변수는 내장된 출력에 이미지 필터를 적용할지 여부를 제어하는 부울 값을 받습니다. 이미지 최적화 필터를 사용하면 특히 저품질 스캔 이미지를 처리할 때 OCR 정확도를 크게 향상시킬 수 있습니다.

아래 예제는 그레이스케일 필터를 적용하고, 두 번째 인수로 true를 전달하여 필터링된 이미지를 검색 가능한 PDF 출력물에 삽입합니다.

:path=/static-assets/ocr/content-code-examples/how-to/image-quality-correction-searchable-pdf.cs
using IronOcr;

var ocr = new IronTesseract();
var ocrInput = new OcrInput();

// Load a PDF file
ocrInput.LoadPdf("invoice.pdf");

// Apply gray scale filter
ocrInput.ToGrayScale();
OcrResult result = ocr.Read(ocrInput);

// Save the result as a searchable PDF with filters applied
result.SaveAsSearchablePdf("outputGrayscale.pdf", true);
Imports IronOcr

Dim ocr As New IronTesseract()
Dim ocrInput As New OcrInput()

' Load a PDF file
ocrInput.LoadPdf("invoice.pdf")

' Apply gray scale filter
ocrInput.ToGrayScale()
Dim result As OcrResult = ocr.Read(ocrInput)

' Save the result as a searchable PDF with filters applied
result.SaveAsSearchablePdf("outputGrayscale.pdf", True)
$vbLabelText   $csharpLabel

최적의 결과를 얻으려면 필터 마법사를 사용하여 특정 문서 유형에 맞는 최적의 필터 조합을 자동으로 찾는 것이 좋습니다. 이 도구는 입력 내용을 분석하여 적절한 전처리 단계를 제안합니다.

검색 가능한 PDF 파일에서 잘못된 문자를 어떻게 수정하나요?

PDF에서 텍스트가 시각적으로는 올바르게 표시되지만 검색하거나 복사할 때 문자가 깨져서 나타나는 경우, 이는 검색 가능한 텍스트 레이어에 사용된 기본 글꼴 때문입니다. 기본적으로 SaveAsSearchablePdf은 Times New Roman을 사용하며, 이 글꼴은 모든 유니코드 문자를 완벽하게 지원하지 않습니다. 이는 악센트가 있거나 ASCII 문자가 아닌 문자를 사용하는 언어에 영향을 미칩니다.

이 문제를 해결하려면 세 번째 매개변수로 유니코드 호환 글꼴 파일을 제공하십시오.

result.SaveAsSearchablePdf("output.pdf", false, "Fonts/LiberationSerif-Regular.ttf");
result.SaveAsSearchablePdf("output.pdf", false, "Fonts/LiberationSerif-Regular.ttf");
result.SaveAsSearchablePdf("output.pdf", False, "Fonts/LiberationSerif-Regular.ttf")
$vbLabelText   $csharpLabel

네 번째 매개변수로 사용자 지정 글꼴 이름을 지정할 수도 있습니다.

result.SaveAsSearchablePdf("output.pdf", false, "Fonts/LiberationSerif-Regular.ttf", "MyFont");
result.SaveAsSearchablePdf("output.pdf", false, "Fonts/LiberationSerif-Regular.ttf", "MyFont");
result.SaveAsSearchablePdf("output.pdf", False, "Fonts/LiberationSerif-Regular.ttf", "MyFont")
$vbLabelText   $csharpLabel

이는 OcrResult, OcrPhotoResult, OcrDocAdvancedResult을 포함한 모든 결과 유형에 적용되므로, 어떤 읽기 메서드가 결과를 생성했는지와 관계없이 수정 사항이 적용됩니다.

참고해 주세요원래 Times New Roman으로 조판된 문서의 경우, 원래 간격과 레이아웃을 유지하면서 운율적으로 호환되는 Liberation Serif를 사용하는 것이 좋습니다. 일반적인 다국어 사용에는 Noto Sans 또는 DejaVu Sans가 좋은 대안입니다.

파일 경로에 쓰기가 불가능한 경우, IronOCR은 검색 가능한 PDF를 바이트 배열이나 스트림으로 반환하는 기능도 지원합니다.


검색 가능한 PDF 파일을 바이트 또는 스트림 형식으로 내보내는 방법은 무엇인가요?

검색 가능한 PDF의 출력은 각각 SaveAsSearchablePdfBytesSaveAsSearchablePdfStream 메서드를 사용하여 바이트 또는 스트림으로 처리할 수도 있습니다. 아래 코드 예제는 이러한 메서드를 사용하는 방법을 보여줍니다.

:path=/static-assets/ocr/content-code-examples/how-to/searchable-pdf-searchable-pdf-byte-stream.cs
// Export searchable PDF byte
byte[] pdfByte = ocrResult.SaveAsSearchablePdfBytes();

// Export searchable PDF stream
Stream pdfStream = ocrResult.SaveAsSearchablePdfStream();
' Export searchable PDF byte
Dim pdfByte() As Byte = ocrResult.SaveAsSearchablePdfBytes()

' Export searchable PDF stream
Dim pdfStream As Stream = ocrResult.SaveAsSearchablePdfStream()
$vbLabelText   $csharpLabel

이러한 출력 옵션은 파일 시스템 접근이 제한될 수 있는 클라우드 스토리지 서비스, 데이터베이스 또는 웹 애플리케이션과 통합할 때 특히 유용합니다. 아래 예시는 실제 적용 사례를 보여줍니다:

using IronOcr;
using System.IO;

public class SearchablePdfExporter
{
    public async Task ProcessAndUploadPdf(string inputPath)
    {
        var ocr = new IronTesseract
        {
            Configuration = { RenderSearchablePdf = true }
        };

        // Process the input
        using var input = new OcrImageInput(inputPath);
        var result = ocr.Read(input);

        // Option 1: Save to database as byte array
        byte[] pdfBytes = result.SaveAsSearchablePdfBytes();
        // Store pdfBytes in database BLOB field

        // Option 2: Upload to cloud storage using stream
        using (Stream pdfStream = result.SaveAsSearchablePdfStream())
        {
            // Upload stream to Azure Blob Storage, AWS S3, etc.
            await UploadToCloudStorage(pdfStream, "searchable-output.pdf");
        }

        // Option 3: Return as web response
        // return File(pdfBytes, "application/pdf", "searchable.pdf");
    }

    private async Task UploadToCloudStorage(Stream stream, string fileName)
    {
        // Cloud upload implementation
    }
}
using IronOcr;
using System.IO;

public class SearchablePdfExporter
{
    public async Task ProcessAndUploadPdf(string inputPath)
    {
        var ocr = new IronTesseract
        {
            Configuration = { RenderSearchablePdf = true }
        };

        // Process the input
        using var input = new OcrImageInput(inputPath);
        var result = ocr.Read(input);

        // Option 1: Save to database as byte array
        byte[] pdfBytes = result.SaveAsSearchablePdfBytes();
        // Store pdfBytes in database BLOB field

        // Option 2: Upload to cloud storage using stream
        using (Stream pdfStream = result.SaveAsSearchablePdfStream())
        {
            // Upload stream to Azure Blob Storage, AWS S3, etc.
            await UploadToCloudStorage(pdfStream, "searchable-output.pdf");
        }

        // Option 3: Return as web response
        // return File(pdfBytes, "application/pdf", "searchable.pdf");
    }

    private async Task UploadToCloudStorage(Stream stream, string fileName)
    {
        // Cloud upload implementation
    }
}
Imports IronOcr
Imports System.IO
Imports System.Threading.Tasks

Public Class SearchablePdfExporter
    Public Async Function ProcessAndUploadPdf(inputPath As String) As Task
        Dim ocr As New IronTesseract With {
            .Configuration = New TesseractConfiguration With {
                .RenderSearchablePdf = True
            }
        }

        ' Process the input
        Using input As New OcrImageInput(inputPath)
            Dim result = ocr.Read(input)

            ' Option 1: Save to database as byte array
            Dim pdfBytes As Byte() = result.SaveAsSearchablePdfBytes()
            ' Store pdfBytes in database BLOB field

            ' Option 2: Upload to cloud storage using stream
            Using pdfStream As Stream = result.SaveAsSearchablePdfStream()
                ' Upload stream to Azure Blob Storage, AWS S3, etc.
                Await UploadToCloudStorage(pdfStream, "searchable-output.pdf")
            End Using

            ' Option 3: Return as web response
            ' Return File(pdfBytes, "application/pdf", "searchable.pdf")
        End Using
    End Function

    Private Async Function UploadToCloudStorage(stream As Stream, fileName As String) As Task
        ' Cloud upload implementation
    End Function
End Class
$vbLabelText   $csharpLabel

성능 고려 사항

대량의 문서를 처리할 때는 처리량 향상을 위해 멀티스레드 OCR 작업을 구현하는 것을 고려하십시오. IronOCR은 동시 처리를 지원하므로 여러 문서를 동시에 처리할 수 있습니다.

using IronOcr;
using System.Threading.Tasks;
using System.Collections.Concurrent;

public class BatchPdfProcessor
{
    private readonly IronTesseract _ocr;

    public BatchPdfProcessor()
    {
        _ocr = new IronTesseract
        {
            Configuration = 
            {
                RenderSearchablePdf = true,
                // Configure for optimal performance
                Language = OcrLanguage.English
            }
        };
    }

    public async Task ProcessBatchAsync(string[] filePaths)
    {
        var results = new ConcurrentBag<(string source, string output)>();

        await Parallel.ForEachAsync(filePaths, async (filePath, ct) =>
        {
            using var input = new OcrImageInput(filePath);
            var result = _ocr.Read(input);

            string outputPath = Path.ChangeExtension(filePath, ".searchable.pdf");
            result.SaveAsSearchablePdf(outputPath);

            results.Add((filePath, outputPath));
        });

        Console.WriteLine($"Processed {results.Count} files");
    }
}
using IronOcr;
using System.Threading.Tasks;
using System.Collections.Concurrent;

public class BatchPdfProcessor
{
    private readonly IronTesseract _ocr;

    public BatchPdfProcessor()
    {
        _ocr = new IronTesseract
        {
            Configuration = 
            {
                RenderSearchablePdf = true,
                // Configure for optimal performance
                Language = OcrLanguage.English
            }
        };
    }

    public async Task ProcessBatchAsync(string[] filePaths)
    {
        var results = new ConcurrentBag<(string source, string output)>();

        await Parallel.ForEachAsync(filePaths, async (filePath, ct) =>
        {
            using var input = new OcrImageInput(filePath);
            var result = _ocr.Read(input);

            string outputPath = Path.ChangeExtension(filePath, ".searchable.pdf");
            result.SaveAsSearchablePdf(outputPath);

            results.Add((filePath, outputPath));
        });

        Console.WriteLine($"Processed {results.Count} files");
    }
}
Imports IronOcr
Imports System.Threading.Tasks
Imports System.Collections.Concurrent

Public Class BatchPdfProcessor
    Private ReadOnly _ocr As IronTesseract

    Public Sub New()
        _ocr = New IronTesseract With {
            .Configuration = New OcrConfiguration With {
                .RenderSearchablePdf = True,
                ' Configure for optimal performance
                .Language = OcrLanguage.English
            }
        }
    End Sub

    Public Async Function ProcessBatchAsync(filePaths As String()) As Task
        Dim results As New ConcurrentBag(Of (source As String, output As String))()

        Await Task.Run(Sub()
                           Parallel.ForEach(filePaths, Sub(filePath)
                                                           Using input As New OcrImageInput(filePath)
                                                               Dim result = _ocr.Read(input)

                                                               Dim outputPath As String = Path.ChangeExtension(filePath, ".searchable.pdf")
                                                               result.SaveAsSearchablePdf(outputPath)

                                                               results.Add((filePath, outputPath))
                                                           End Using
                                                       End Sub)
                       End Sub)

        Console.WriteLine($"Processed {results.Count} files")
    End Function
End Class
$vbLabelText   $csharpLabel

고급 구성 옵션

보다 고급 시나리오의 경우, 상세한 Tesseract 구성을 활용하여 특정 문서 유형 또는 언어에 맞게 OCR 엔진을 세밀하게 조정할 수 있습니다.

var advancedOcr = new IronTesseract
{
    Configuration = 
    {
        RenderSearchablePdf = true,
        TesseractVariables = new Dictionary<string, object>
        {
            { "preserve_interword_spaces", 1 },
            { "tessedit_char_whitelist", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" }
        },
        PageSegmentationMode = TesseractPageSegmentationMode.SingleColumn
    },
    Language = OcrLanguage.EnglishBest
};
var advancedOcr = new IronTesseract
{
    Configuration = 
    {
        RenderSearchablePdf = true,
        TesseractVariables = new Dictionary<string, object>
        {
            { "preserve_interword_spaces", 1 },
            { "tessedit_char_whitelist", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" }
        },
        PageSegmentationMode = TesseractPageSegmentationMode.SingleColumn
    },
    Language = OcrLanguage.EnglishBest
};
Imports IronOcr

Dim advancedOcr As New IronTesseract With {
    .Configuration = New TesseractConfiguration With {
        .RenderSearchablePdf = True,
        .TesseractVariables = New Dictionary(Of String, Object) From {
            {"preserve_interword_spaces", 1},
            {"tessedit_char_whitelist", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"}
        },
        .PageSegmentationMode = TesseractPageSegmentationMode.SingleColumn
    },
    .Language = OcrLanguage.EnglishBest
}
$vbLabelText   $csharpLabel

이 구성 옵션은 SaveAsSearchablePdf, SaveAsSearchablePdfBytes, SaveAsSearchablePdfStream의 세 가지 출력 방식 모두에 동일하게 적용됩니다. 아래 요약에는 검색 가능한 모든 PDF 처리 방법과 해당 출력 형식이 정리되어 있습니다.

요약

IronOCR을 사용하면 검색 가능한 PDF를 쉽고 유연하게 만들 수 있습니다. 단일 이미지, 다중 페이지 문서, ReadPhoto를 통한 사진, 또는 ReadDocumentAdvanced를 통한 고급 문서 스캔을 처리해야 하는 경우, 이 라이브러리는 다양한 형식의 검색 가능한 PDF를 생성할 수 있는 강력한 메서드를 제공합니다. 정확도를 높이기 위해 ModelType 매개변수를 사용하여 표준 ML 모델과 향상된 ML 모델 중 하나를 선택하십시오. 파일, 바이트 또는 스트림으로 내보낼 수 있는 기능 덕분에 데스크톱 애플리케이션부터 클라우드 기반 서비스에 이르기까지 모든 애플리케이션 아키텍처에 적용할 수 있습니다.

더 복잡한 OCR 시나리오의 경우, 포괄적인 코드 예제를 살펴보거나 API 문서를 참조하여 자세한 메서드 시그니처와 옵션을 확인하십시오.

자주 묻는 질문

C#에서 스캔한 이미지를 검색 가능한 PDF로 만드는 방법은 무엇인가요?

IronOCR을 사용하면 스캔한 이미지에서 검색 가능한 PDF를 간편하게 생성할 수 있습니다. 설정에서 RenderSearchablePdf를 true로 설정하고, 입력 이미지에서 Read() 메서드를 호출한 다음, 원하는 출력 경로와 함께 SaveAsSearchablePdf() 메서드를 호출하기만 하면 됩니다. IronOCR은 이미지에 OCR을 적용하여 원본 이미지 위에 선택 및 검색 가능한 텍스트가 오버레이된 PDF를 생성합니다.

검색 가능한 PDF로 변환할 수 있는 파일 형식은 무엇인가요?

IronOCR은 JPG, PNG, TIFF를 비롯한 다양한 이미지 형식과 기존 PDF 문서를 검색 가능한 PDF로 변환할 수 있습니다. 이 라이브러리는 단일 페이지 이미지와 TIFF 파일과 같은 여러 페이지 문서를 모두 지원하며, 모든 페이지를 자동으로 처리하고 출력 검색 가능 PDF에서 페이지 순서를 올바르게 유지합니다.

검색 가능한 PDF 파일을 일반 파일 대신 바이트 배열이나 스트림으로 내보낼 수 있나요?

네, IronOCR은 검색 가능한 PDF 파일을 다양한 형식으로 내보낼 수 있도록 지원합니다. SaveAsSearchablePdf() 함수를 사용하여 파일에 직접 저장하는 것 외에도, OCR 결과를 바이트 배열이나 스트림으로 내보낼 수 있어 임시 파일을 생성하지 않고도 웹 애플리케이션, 클라우드 스토리지 또는 데이터베이스 시스템과 쉽게 통합할 수 있습니다.

검색 가능한 PDF를 생성하는 데 필요한 최소 코드는 무엇입니까?

IronOCR을 사용하여 검색 가능한 PDF를 생성하는 것은 단 한 줄의 코드로 가능합니다. `new IronOcr.IronTesseract { Configuration = { RenderSearchablePdf = true } }.Read(new IronOcr.OcrImageInput("file.jpg")).SaveAsSearchablePdf("searchable.pdf")`. 이는 IronOCR의 간소화된 API 설계를 보여줍니다.

검색 가능한 PDF에서 보이지 않는 텍스트 레이어는 어떻게 작동하나요?

IronOCR은 인식된 텍스트의 위치를 PDF 원본 이미지 위에 보이지 않는 레이어로 자동으로 처리합니다. 이를 통해 정확한 텍스트-이미지 매핑이 보장되어, 사용자는 원본 문서의 시각적 모양을 유지한 채 텍스트를 선택하고 검색할 수 있습니다. 이 라이브러리는 이를 달성하기 위해 특수한 폰트와 위치 지정 알고리즘을 사용합니다.

사진이나 스크린샷으로 검색 가능한 PDF를 만들 수 있나요?

네, SaveAsSearchablePdf는 ReadPhoto, ReadScreenShotReadDocumentAdvanced의 결과에서 지원됩니다. 각 메서드는 검색 가능한 PDF 내보내기를 지원하는 결과 유형을 반환하므로, 실제 사진, 스크린샷 또는 복잡한 문서 스캔을 검색 가능한 PDF로 쉽게 변환할 수 있습니다.

ModelType 매개변수는 어떤 역할을 하나요?

ModelType 매개변수는 OCR에 사용할 사전 훈련된 ML 모델을 제어합니다. Normal은 기본값으로, 빠른 결과를 위해 960픽셀로 크기가 조정된 이미지를 처리합니다. Enhanced는 최대 2560픽셀의 이미지를 지원하여, 고해상도 입력에 대해 더 세밀한 디테일을 유지하고 정확도를 향상시킵니다.

검색 가능한 PDF에서 복사하거나 검색한 문자가 왜 깨져 보이나요?

이는 검색 가능한 텍스트 레이어에 사용되는 기본 글꼴(Times New Roman)이 모든 유니코드 문자를 완벽하게 지원하지 않기 때문입니다. 이 문제를 해결하려면 SaveAsSearchablePdf의 세 번째 매개변수로 유니코드 호환 글꼴 파일을 전달하십시오. 문서가 원래 Times New Roman으로 조판되었고 다른 글꼴에서 간격 불일치가 발생하는 경우, 동일한 글리프 메트릭을 공유하고 원래 레이아웃을 유지하는 Liberation Serif를 사용해 보십시오.

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

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

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

검토자:
제프 프리츠
제프리 T. 프리츠
.NET 커뮤니티 팀의 수석 프로그램 관리자
제프는 .NET 및 Visual Studio 팀의 수석 프로그램 관리자이기도 합니다. 그는 .NET Conf 가상 컨퍼런스 시리즈의 총괄 프로듀서이며, 개발자를 위한 라이브 스트림 'Fritz and Friends'를 주 2회 진행하며 시청자들과 함께 기술에 대해 이야기하고 코드를 작성합니다. 제프는 Microsoft Build, Microsoft Ignite, .NET Conf, Microsoft MVP Summit 등 주요 Microsoft 개발자 행사를 위한 워크숍, 프레젠테이션 및 콘텐츠 기획을 담당합니다.
시작할 준비 되셨나요?
Nuget 다운로드 5,570,591 | 버전: 2026.4 방금 출시되었습니다
Still Scrolling Icon

아직도 스크롤하고 계신가요?

빠른 증거를 원하시나요? PM > Install-Package IronOcr
샘플을 실행하세요 이미지가 검색 가능한 텍스트로 바뀌는 것을 확인해 보세요.