푸터 콘텐츠로 바로가기
IRONPDF 사용하기

VB.NET에서 PDF를 TIFF로 변환하는 방법

Windows Forms 애플리케이션 내에서 PDF 페이지를 표시하는 것은 문서 관리 도구, 보고서 뷰어, 파일 미리보기 유틸리티에 대해 일반적인 요구 사항입니다. PictureBox 컨트롤은 이미 양식에서 이미지 렌더링을 처리하기 때문에 자연스러운 후보입니다. 문제는 PDF 파일이 이미지가 아니라는 것입니다 -- 표준 이미지 컨트롤이 표시할 수 있도록 하기 전에 전문적인 렌더링이 필요합니다. 이 가이드는 ChromePdfRenderer를 사용하여 PDF 페이지를 비트맵 이미지로 변환하고 페이지 내비게이션, 인쇄 및 저장 지원과 함께 PictureBox 컨트롤 내부에 표시하는 방법을 안내합니다.

지금 바로 IronPDF으로 시작하세요.
green arrow pointer

왜 PictureBox가 PDF 파일을 직접 표시할 수 없나요?

Windows Forms의 PictureBox 컨트롤은 BMP, PNG, JPG, GIF, TIFF 및 몇 가지 다른 이미지 형식을 위한 것입니다. PDF 파일 경로를 PictureBox.ImageLocation에 지정하거나 PDF 스트림을 PictureBox.Image에 로드하려고 할 때, PDF 바이너리 형식이 인식된 이미지 형식이 아니기 때문에 컨트롤은 예외를 던집니다.

일부 접근 방식은 COM 인터롭을 통한 Adobe Acrobat을 포함하여 이를 해결하려고 합니다. 이는 애플리케이션을 실행하는 모든 컴퓨터에 Adobe Reader가 설치되어 있어야 하는 의존성이 생기며, 기업 환경에서 관리하기 어려운 배포 제한을 초래합니다. 또한 사용자가 가지고 있는 Acrobat의 버전에 따라 렌더링 엔진이 고정되어 있어 여러 대의 컴퓨터에서 호환성 문제가 발생할 수 있습니다.

보다 깔끔한 접근 방식은 런타임에 PDF 페이지를 비트맵 이미지로 변환하는 .NET PDF 라이브러리를 사용하는 것입니다. ChromePdfRendererToBitmap 메서드를 통해 이를 가능하게 하며, PDF 문서의 각 페이지를 AnyBitmap 객체로 렌더링합니다. 그런 다음 해당 객체를 표준 System.Drawing.Bitmap로 변환하고 PictureBox.Image에 직접 할당할 수 있습니다. Adobe 설치가 필요 없고, COM 등록이 없으며, 애플리케이션 창에 외부 뷰어가 포함되지 않습니다.

이 기법은 .NET Framework 4.6.2 이상, 그리고 Windows에서 .NET 6, 8, 10에 걸쳐 작동합니다. ChromePdfRenderer의 렌더링 엔진은 Chrome 기반으로, 복잡한 레이아웃, 내장 폰트 및 이미지/텍스트 혼합 콘텐츠를 포함한 PDF에서도 고품질 출력을 생성합니다.

Windows Forms 프로젝트에 ChromePdfRenderer를 설치하는 방법은?

코드를 작성하기 전에 ChromePdfRenderer를 프로젝트에 추가해야 합니다. 가장 빠른 방법은 NuGet 패키지 관리자 CLI를 통해 설치하는 것입니다:

dotnet add package IronPdf

또는 Visual Studio 패키지 관리 콘솔을 사용하십시오:

Install-Package IronPdf

설치 후 .csproj 파일에 패키지 참조가 나타나는지 확인하세요. ChromePdfRenderer는 .NET 6 이상에서 Windows를 대상으로 하므로, 프로젝트 파일에서 플랫폼 간 대상을 사용하는 경우 Windows에 대한 <RuntimeIdentifiers> 또는 <Platforms> 제한을 추가하세요. Windows Forms 프로젝트의 경우 Visual Studio에서 프로젝트 템플릿을 생성할 때 일반적으로 이미 설정되어 있습니다.

운영 환경에서 라이선스를 사용하기 위해 ChromePdfRenderer 호출 전에 애플리케이션 시작 코드에 라이선스 키를 입력하세요:

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

개발 및 평가 중에는 ChromePdfRenderer가 체험판 모드로 실행되며, 이는 렌더링된 출력에 워터마크를 추가합니다. 무료 체험 라이선스는 테스트 목적을 위해 워터마크를 제거합니다.

Windows Forms 프로젝트 구조 설정 방법은?

Visual Studio를 열고 .NET 10을 대상으로 하는 새로운 Windows Forms App 프로젝트를 만드세요. 프로젝트 템플릿은 Form1.csProgram.cs 엔트리 포인트를 생성합니다.

디자이너 표면에서 폼에 다음 컨트롤을 추가합니다:

  • 양식의 대부분을 덮는 pictureBoxPdf이라는 이름의 PictureBox, SizeModeZoom로 설정됨
  • 'Open PDF'라는 텍스트가 있는 btnOpen이라는 이름의 Button
  • 'Previous'라는 텍스트가 있는 btnPrevious이라는 이름의 Button
  • 'Next'라는 텍스트가 있는 btnNext이라는 이름의 Button
  • 'Save Page'라는 텍스트가 있는 btnSave이라는 이름의 Button
  • 'Print'라는 텍스트가 있는 btnPrint이라는 이름의 Button
  • 현재 페이지 번호를 표시하는 lblPageInfo 이름의 Label

PictureBoxSizeMode = Zoom 설정은 PDF 페이지가 비율을 왜곡하지 않고 컨트롤에 맞도록 비례적으로 확대 또는 축소되도록 보장합니다. 이는 PDF 페이지의 크기가 다르기 때문에 중요합니다 -- 편지 용지, A4 및 법률 형식 모두 다른 차원을 가지고 있고 뷰어가 모든 것을 매끄럽게 처리하도록 하고 싶습니다.

다음은 PDF 뷰어 응용 프로그램에 대한 전체 폼 코드입니다. 이는 Program.cs의 최상위 문장을 사용하며 전체 뷰어 로직을 Form1.cs에 넣습니다:

using IronPdf;
using IronSoftware.Drawing;
using System.Drawing;

public partial class Form1 : Form
{
    private PdfDocument? currentPdf;
    private AnyBitmap[]? pageImages;
    private int currentPageIndex = 0;

    public Form1()
    {
        InitializeComponent();
        pictureBoxPdf.SizeMode = PictureBoxSizeMode.Zoom;
        UpdateNavigationState();
    }

    private void UpdateNavigationState()
    {
        bool hasPdf = pageImages != null && pageImages.Length > 0;
        btnPrevious.Enabled = hasPdf && currentPageIndex > 0;
        btnNext.Enabled = hasPdf && currentPageIndex < (pageImages?.Length - 1 ?? 0);
        btnSave.Enabled = hasPdf;
        btnPrint.Enabled = hasPdf;
        lblPageInfo.Text = hasPdf
            ? $"Page {currentPageIndex + 1} of {pageImages!.Length}"
            : "No document loaded";
    }
}
using IronPdf;
using IronSoftware.Drawing;
using System.Drawing;

public partial class Form1 : Form
{
    private PdfDocument? currentPdf;
    private AnyBitmap[]? pageImages;
    private int currentPageIndex = 0;

    public Form1()
    {
        InitializeComponent();
        pictureBoxPdf.SizeMode = PictureBoxSizeMode.Zoom;
        UpdateNavigationState();
    }

    private void UpdateNavigationState()
    {
        bool hasPdf = pageImages != null && pageImages.Length > 0;
        btnPrevious.Enabled = hasPdf && currentPageIndex > 0;
        btnNext.Enabled = hasPdf && currentPageIndex < (pageImages?.Length - 1 ?? 0);
        btnSave.Enabled = hasPdf;
        btnPrint.Enabled = hasPdf;
        lblPageInfo.Text = hasPdf
            ? $"Page {currentPageIndex + 1} of {pageImages!.Length}"
            : "No document loaded";
    }
}
Imports IronPdf
Imports IronSoftware.Drawing
Imports System.Drawing

Public Partial Class Form1
    Inherits Form

    Private currentPdf As PdfDocument
    Private pageImages As AnyBitmap()
    Private currentPageIndex As Integer = 0

    Public Sub New()
        InitializeComponent()
        pictureBoxPdf.SizeMode = PictureBoxSizeMode.Zoom
        UpdateNavigationState()
    End Sub

    Private Sub UpdateNavigationState()
        Dim hasPdf As Boolean = pageImages IsNot Nothing AndAlso pageImages.Length > 0
        btnPrevious.Enabled = hasPdf AndAlso currentPageIndex > 0
        btnNext.Enabled = hasPdf AndAlso currentPageIndex < If(pageImages?.Length - 1, 0)
        btnSave.Enabled = hasPdf
        btnPrint.Enabled = hasPdf
        lblPageInfo.Text = If(hasPdf, $"Page {currentPageIndex + 1} of {pageImages.Length}", "No document loaded")
    End Sub
End Class
$vbLabelText   $csharpLabel

UpdateNavigationState 도우미 메서드는 PDF가 로드되었는지 여부와 뷰어가 현재 어떤 페이지를 표시하고 있는지를 기준으로 내비게이션 및 액션 버튼을 비활성화하거나 활성화합니다. 이는 사용자가 문서를 로드하기 전에 버튼을 클릭할 때 null 참조 오류를 방지합니다.

VB .NET PictureBox에서 PDF 표시: Windows Forms에서 이미지를 PDF 페이지로 렌더링하기: 이미지 1 - ChromePdfRenderer 설치

PDF 페이지를 PictureBox로 로드하고 렌더링하는 방법은?

PictureBox에 PDF를 로드하고 렌더링하는 것은 문서를 PdfDocument.FromFile으로 로드한 다음, 모든 페이지를 비트맵 객체 배열로 변환하는 ToBitmap을 호출하는 두 단계로 이루어집니다.

PDF를 이미지로 변환하는 방법 ToBitmap은 요청된 DPI로 모든 페이지를 렌더링합니다. 높은 DPI는 더 선명한 이미지를 생성하지만 더 많은 메모리를 사용합니다. 보통 150 DPI는 문서 뷰어에 적합한 균형을 이룹니다 -- 화면에서 읽을 수 있으며 대형 문서를 위한 기가바이트의 RAM이 필요하지 않습니다.

private void btnOpen_Click(object sender, EventArgs e)
{
    using OpenFileDialog openDialog = new OpenFileDialog();
    openDialog.Filter = "PDF Files|*.pdf";
    openDialog.Title = "Select a PDF Document";

    if (openDialog.ShowDialog() == DialogResult.OK)
    {
        LoadPdfDocument(openDialog.FileName);
    }
}

private void LoadPdfDocument(string filePath)
{
    currentPdf?.Dispose();
    currentPdf = PdfDocument.FromFile(filePath);

    // Render all pages as bitmaps at 150 DPI
    pageImages = currentPdf.ToBitmap(150);
    currentPageIndex = 0;

    DisplayCurrentPage();
    UpdateNavigationState();
}

private void DisplayCurrentPage()
{
    if (pageImages == null || pageImages.Length == 0) return;

    // Convert AnyBitmap to System.Drawing.Bitmap for PictureBox
    System.Drawing.Bitmap bitmap = pageImages[currentPageIndex].ToImage<System.Drawing.Bitmap>();
    pictureBoxPdf.Image?.Dispose();
    pictureBoxPdf.Image = bitmap;

    UpdateNavigationState();
}
private void btnOpen_Click(object sender, EventArgs e)
{
    using OpenFileDialog openDialog = new OpenFileDialog();
    openDialog.Filter = "PDF Files|*.pdf";
    openDialog.Title = "Select a PDF Document";

    if (openDialog.ShowDialog() == DialogResult.OK)
    {
        LoadPdfDocument(openDialog.FileName);
    }
}

private void LoadPdfDocument(string filePath)
{
    currentPdf?.Dispose();
    currentPdf = PdfDocument.FromFile(filePath);

    // Render all pages as bitmaps at 150 DPI
    pageImages = currentPdf.ToBitmap(150);
    currentPageIndex = 0;

    DisplayCurrentPage();
    UpdateNavigationState();
}

private void DisplayCurrentPage()
{
    if (pageImages == null || pageImages.Length == 0) return;

    // Convert AnyBitmap to System.Drawing.Bitmap for PictureBox
    System.Drawing.Bitmap bitmap = pageImages[currentPageIndex].ToImage<System.Drawing.Bitmap>();
    pictureBoxPdf.Image?.Dispose();
    pictureBoxPdf.Image = bitmap;

    UpdateNavigationState();
}
Private Sub btnOpen_Click(sender As Object, e As EventArgs) Handles btnOpen.Click
    Using openDialog As New OpenFileDialog()
        openDialog.Filter = "PDF Files|*.pdf"
        openDialog.Title = "Select a PDF Document"

        If openDialog.ShowDialog() = DialogResult.OK Then
            LoadPdfDocument(openDialog.FileName)
        End If
    End Using
End Sub

Private Sub LoadPdfDocument(filePath As String)
    currentPdf?.Dispose()
    currentPdf = PdfDocument.FromFile(filePath)

    ' Render all pages as bitmaps at 150 DPI
    pageImages = currentPdf.ToBitmap(150)
    currentPageIndex = 0

    DisplayCurrentPage()
    UpdateNavigationState()
End Sub

Private Sub DisplayCurrentPage()
    If pageImages Is Nothing OrElse pageImages.Length = 0 Then Return

    ' Convert AnyBitmap to System.Drawing.Bitmap for PictureBox
    Dim bitmap As System.Drawing.Bitmap = pageImages(currentPageIndex).ToImage(Of System.Drawing.Bitmap)()
    pictureBoxPdf.Image?.Dispose()
    pictureBoxPdf.Image = bitmap

    UpdateNavigationState()
End Sub
$vbLabelText   $csharpLabel

PdfDocument.FromFile 메서드는 PDF를 디스크에서 메모리로 로드합니다. DPI 매개변수로 ToBitmap을 호출하면 페이지당 하나의 AnyBitmap 객체 배열을 반환합니다. AnyBitmap 타입은 ChromePdfRenderer의 형식 불문 비트맵 클래스이며, ToImage<System.Drawing.Bitmap>()은 그것을 PictureBox.Image이 기대하는 System.Drawing.Bitmap 타입으로 변환합니다.

이전 PictureBox.Image가 새로운 것으로 할당되기 전에 삭제되는 점을 주목하세요. 이는 중요합니다 -- 각 Bitmap 객체는 관리되지 않는 GDI+ 리소스를 보유하고 있으며, 오래된 비트맵을 삭제하지 않으면 장기 실행 응용 프로그램에서 메모리 누수가 발생합니다.

VB .NET PictureBox에서 PDF 표시: Windows Forms에서 이미지를 PDF 페이지로 렌더링하기: 이미지 2 - 사용 준비가 완료된 빈 윈도우 폼 예시

로드 후에 뷰어는 첫 번째 페이지를 즉시 표시합니다. lblPageInfo 레이블이 현재 페이지 번호와 전체 페이지 수를 표시하도록 업데이트됩니다.

VB .NET PictureBox에서 PDF 표시: Windows Forms에서 이미지를 PDF 페이지로 렌더링하기: 이미지 3 - 뷰어에 표시된 입력 PDF의 예

PDF 페이지 간에 페이지 네비게이션을 어떻게 추가하나요?

첫 페이지만 표시하는 PDF 뷰어는 여러 페이지가 있는 문서에 유용하지 않습니다. 네비게이션 버튼은 사용자들이 렌더링된 페이지 배열을 앞뒤로 이동할 수 있게 합니다:

private void btnPrevious_Click(object sender, EventArgs e)
{
    if (currentPageIndex > 0)
    {
        currentPageIndex--;
        DisplayCurrentPage();
    }
}

private void btnNext_Click(object sender, EventArgs e)
{
    if (pageImages != null && currentPageIndex < pageImages.Length - 1)
    {
        currentPageIndex++;
        DisplayCurrentPage();
    }
}
private void btnPrevious_Click(object sender, EventArgs e)
{
    if (currentPageIndex > 0)
    {
        currentPageIndex--;
        DisplayCurrentPage();
    }
}

private void btnNext_Click(object sender, EventArgs e)
{
    if (pageImages != null && currentPageIndex < pageImages.Length - 1)
    {
        currentPageIndex++;
        DisplayCurrentPage();
    }
}
Private Sub btnPrevious_Click(sender As Object, e As EventArgs)
    If currentPageIndex > 0 Then
        currentPageIndex -= 1
        DisplayCurrentPage()
    End If
End Sub

Private Sub btnNext_Click(sender As Object, e As EventArgs)
    If pageImages IsNot Nothing AndAlso currentPageIndex < pageImages.Length - 1 Then
        currentPageIndex += 1
        DisplayCurrentPage()
    End If
End Sub
$vbLabelText   $csharpLabel

각 클릭 핸들러가 currentPageIndex을 1씩 조정하고 DisplayCurrentPage을 호출하는데, 이는 해당하는 비트맵으로 PictureBox.Image을 교체합니다. 경계 검사 (currentPageIndex > 0currentPageIndex < pageImages.Length - 1)는 인덱스 초과 예외를 방지하며, UpdateNavigationState은 또한 범위를 벗어날 경우 버튼을 비활성화합니다.

더 큰 문서의 경우, 사용자가 특정 페이지 번호를 입력하여 해당 페이지로 직접 이동할 수 있는 페이지 번호 입력 필드를 추가하거나 측면에 스크롤 가능한 섬네일 스트립을 추가하는 것도 고려할 수 있습니다. pageImages 배열에 이미 렌더링된 모든 페이지가 포함되어 있으므로 특정 페이지로 점프하는 것은 currentPageIndex을 목표 인덱스로 설정하고 DisplayCurrentPage을 호출하는 문제일 뿐입니다.

VB .NET PictureBox에서 PDF 표시: Windows Forms에서 이미지를 PDF 페이지로 렌더링하기: 이미지 4 - 버튼으로 페이지 2로 내비게이션

뷰어에서 PDF 페이지를 저장하고 인쇄하는 방법은?

문서 뷰어는 보통 현재 페이지를 이미지 파일로 저장하고 문서를 프린터로 보내는 것을 지원해야 합니다. ChromePdfRenderer는 이 두 가지를 간단하게 처리합니다.

현재 페이지를 이미지 파일로 저장

현재 페이지는 PictureBox.ImageSystem.Drawing.Bitmap로 이미 사용할 수 있습니다. 사용자가 선택한 파일 확장자로부터 형식을 유추하여 Image.Save을 사용하여 저장하세요:

private void btnSave_Click(object sender, EventArgs e)
{
    if (pictureBoxPdf.Image == null) return;

    using SaveFileDialog saveDialog = new SaveFileDialog();
    saveDialog.Filter = "PNG Image|*.png|JPEG Image|*.jpg|TIFF Image|*.tif";
    saveDialog.Title = "Save Page As Image";
    saveDialog.FileName = $"page_{currentPageIndex + 1}";

    if (saveDialog.ShowDialog() == DialogResult.OK)
    {
        pictureBoxPdf.Image.Save(saveDialog.FileName);
    }
}
private void btnSave_Click(object sender, EventArgs e)
{
    if (pictureBoxPdf.Image == null) return;

    using SaveFileDialog saveDialog = new SaveFileDialog();
    saveDialog.Filter = "PNG Image|*.png|JPEG Image|*.jpg|TIFF Image|*.tif";
    saveDialog.Title = "Save Page As Image";
    saveDialog.FileName = $"page_{currentPageIndex + 1}";

    if (saveDialog.ShowDialog() == DialogResult.OK)
    {
        pictureBoxPdf.Image.Save(saveDialog.FileName);
    }
}
Private Sub btnSave_Click(sender As Object, e As EventArgs)
    If pictureBoxPdf.Image Is Nothing Then Return

    Using saveDialog As New SaveFileDialog()
        saveDialog.Filter = "PNG Image|*.png|JPEG Image|*.jpg|TIFF Image|*.tif"
        saveDialog.Title = "Save Page As Image"
        saveDialog.FileName = $"page_{currentPageIndex + 1}"

        If saveDialog.ShowDialog() = DialogResult.OK Then
            pictureBoxPdf.Image.Save(saveDialog.FileName)
        End If
    End Using
End Sub
$vbLabelText   $csharpLabel

PDF 문서 인쇄

인쇄할 때는 ChromePdfRenderer의 Print 메서드를 사용하여 PDF를 Windows 인쇄 인프라에 직접 전송합니다. 이는 렌더링된 이미지가 아니라 실제 PDF 콘텐츠입니다. 이는 비트맵을 인쇄하는 것보다 훨씬 더 선명한 출력물을 만들어냅니다. 인쇄 드라이버는 래스터화된 이미지가 아닌 벡터 PDF 지침을 받기 때문입니다:

private void btnPrint_Click(object sender, EventArgs e)
{
    if (currentPdf == null) return;

    using PrintDialog printDialog = new PrintDialog();
    if (printDialog.ShowDialog() == DialogResult.OK)
    {
        currentPdf.Print();
    }
}
private void btnPrint_Click(object sender, EventArgs e)
{
    if (currentPdf == null) return;

    using PrintDialog printDialog = new PrintDialog();
    if (printDialog.ShowDialog() == DialogResult.OK)
    {
        currentPdf.Print();
    }
}
Private Sub btnPrint_Click(sender As Object, e As EventArgs)
    If currentPdf Is Nothing Then Return

    Using printDialog As New PrintDialog()
        If printDialog.ShowDialog() = DialogResult.OK Then
            currentPdf.Print()
        End If
    End Using
End Sub
$vbLabelText   $csharpLabel

PrintDialog은 사용자가 대상 프린터를 선택하고 인쇄가 시작되기 전에 설정을 구성할 수 있도록 합니다. 실제 인쇄 작업은 ChromePdfRenderer의 내부 렌더링 엔진이 Windows 스풀러와 통합하여 처리합니다.

VB .NET PictureBox에서 PDF 표시: Windows Forms에서 이미지를 PDF 페이지로 렌더링하기: 이미지 5 - 동작 중인 인쇄 버튼의 예시

메모리와 처리 해제를 올바르게 처리하는 방법은?

특히 고해상도 DPI 설정이나 대형 문서의 경우 PDF 문서와 렌더링된 비트맵은 상당한 메모리를 소모합니다. 적절한 해제가 없으면 장기간 실행되는 뷰어 애플리케이션이 점차 사용 가능한 메모리를 소모하게 됩니다.

처리 해제 체크리스트

이 패턴에서 올바른 해제를 위한 핵심 사항은 다음과 같습니다:

  • 새로운 문서를 로드하기 전에 currentPdf?.Dispose()를 호출합니다. PdfDocumentIDisposable를 구현하고 관리되지 않는 리소스를 보유합니다.
  • 새로운 비트맵을 PictureBox.Image에 할당하기 전에 pictureBoxPdf.Image?.Dispose()를 호출합니다. 각 렌더링된 페이지는 별도의 관리되지 않는 GDI+ 객체입니다.
  • pageImages 배열은 AnyBitmap 객체들을 보유합니다. 페이지에서 벗어나고 더 이상 오래된 비트맵이 필요하지 않을 때, Dispose 호출이 PictureBox.Image에서 System.Drawing.Bitmap 복사를 처리하지만, 새 문서를 로드할 때 배열 내의 AnyBitmap 객체를 삭제하는 것이 좋습니다.

양식이 닫힐 때 Form1.Dispose를 재정의하여 정리합니다:

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        currentPdf?.Dispose();
        pictureBoxPdf.Image?.Dispose();

        if (pageImages != null)
        {
            foreach (var bitmap in pageImages)
                bitmap.Dispose();
        }

        components?.Dispose();
    }
    base.Dispose(disposing);
}
protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        currentPdf?.Dispose();
        pictureBoxPdf.Image?.Dispose();

        if (pageImages != null)
        {
            foreach (var bitmap in pageImages)
                bitmap.Dispose();
        }

        components?.Dispose();
    }
    base.Dispose(disposing);
}
Protected Overrides Sub Dispose(disposing As Boolean)
    If disposing Then
        currentPdf?.Dispose()
        pictureBoxPdf.Image?.Dispose()

        If pageImages IsNot Nothing Then
            For Each bitmap In pageImages
                bitmap.Dispose()
            Next
        End If

        components?.Dispose()
    End If
    MyBase.Dispose(disposing)
End Sub
$vbLabelText   $csharpLabel

이 패턴은 폼이 닫힐 때 모든 ChromePdfRenderer 및 GDI+ 자원이 해제되도록 보장하여 프로덕션 배포 시 메모리 누수를 방지합니다.

모든 페이지 대신 보이는 페이지만 렌더링하는 방법은?

수십 또는 수백 페이지의 대형 PDF의 경우, 모든 페이지를 미리 렌더링하는 ToBitmap은 느리고 메모리를 많이 사용할 수 있습니다. 더 효율적인 방법은 사용자가 보고자 하는 페이지만 필요 시 렌더링하는 것입니다.

ChromePdfRenderer의 RasterizeToImageFiles 접근 방식은 페이지별 렌더링을 지원하지만, 메모리 내 사용을 위해서는 PageCount을 사용하여 한 번에 하나의 페이지만 렌더링할 수도 있습니다:

private void DisplayPageLazy(int pageIndex)
{
    if (currentPdf == null) return;

    // Render only the requested page
    AnyBitmap[] singlePage = currentPdf.ToBitmap(150, pageIndex, pageIndex);

    System.Drawing.Bitmap bitmap = singlePage[0].ToImage<System.Drawing.Bitmap>();
    pictureBoxPdf.Image?.Dispose();
    pictureBoxPdf.Image = bitmap;

    singlePage[0].Dispose();

    lblPageInfo.Text = $"Page {pageIndex + 1} of {currentPdf.PageCount}";
    UpdateNavigationState();
}
private void DisplayPageLazy(int pageIndex)
{
    if (currentPdf == null) return;

    // Render only the requested page
    AnyBitmap[] singlePage = currentPdf.ToBitmap(150, pageIndex, pageIndex);

    System.Drawing.Bitmap bitmap = singlePage[0].ToImage<System.Drawing.Bitmap>();
    pictureBoxPdf.Image?.Dispose();
    pictureBoxPdf.Image = bitmap;

    singlePage[0].Dispose();

    lblPageInfo.Text = $"Page {pageIndex + 1} of {currentPdf.PageCount}";
    UpdateNavigationState();
}
Private Sub DisplayPageLazy(pageIndex As Integer)
    If currentPdf Is Nothing Then Return

    ' Render only the requested page
    Dim singlePage As AnyBitmap() = currentPdf.ToBitmap(150, pageIndex, pageIndex)

    Dim bitmap As System.Drawing.Bitmap = singlePage(0).ToImage(Of System.Drawing.Bitmap)()
    pictureBoxPdf.Image?.Dispose()
    pictureBoxPdf.Image = bitmap

    singlePage(0).Dispose()

    lblPageInfo.Text = $"Page {pageIndex + 1} of {currentPdf.PageCount}"
    UpdateNavigationState()
End Sub
$vbLabelText   $csharpLabel

ToBitmap(dpi, startPage, endPage) 오버로드는 특정 페이지 범위를 렌더링합니다. startPageendPage에 같은 인덱스를 전달하면 한 번에 한 페이지씩만 렌더링됩니다. 이는 매우 큰 문서의 경우 가치 있을 수 있는 낮은 최고 메모리 사용량으로 페이지 당 내비게이션 렌더링 시간을 교환합니다.

ChromePdfRenderer의 이미지 출력 기능에 대한 추가 정보를 보려면 PDF to image 문서PDF 레스터라이징 가이드를 참조하세요.

실용적인 PDF 뷰어는 또한 사용자가 콘텐츠를 확대 및 페이지를 회전할 수 있도록 해야 합니다. 줌의 경우, ToBitmap에 전달되는 DPI를 동적으로 조정하세요 -- currentDpi 필드(150에서 시작)를 저장하고, 줌 버튼 클릭 시 50씩 증가 또는 감소시킨 다음 업데이트된 DPI로 게으른 페이지 렌더러를 호출합니다. 높은 DPI는 Zoom 모드의 PictureBox가 컨트롤에 맞게 확대하거나 축소할 더 큰 이미지를 생성합니다. Math.MinMath.Max을 사용하여 72에서 400 DPI 사이로 범위를 제한하여 낮은 곳에서의 흐릿한 출력이나 높은 곳에서의 과도한 메모리 소비를 방지하세요.

보다 고급 렌더링 옵션, 이미지 렌더링과 함께 PDF에서 텍스트를 추출하는 옵션에 대해 자세히 알아보려면 PDF 텍스트 추출 가이드PDF 이미지 추출 문서를 참조하십시오.

또한 PDF 문서 병합, 워터마크 추가, 텍스트 회전주석 추가를 통해 ChromePdfRenderer의 지원을 살펴보고 더 고급의 뷰어에서 이 기능들을 구현할 수 있습니다.

Windows Forms에 적합한 PDF 렌더링 라이브러리를 선택하는 방법은?

Windows Forms에 적합한 PDF 렌더링 라이브러리를 선택할 때 여러 대안이 있습니다. 옵션을 평가하는 데 도움이 되는 빠른 비교를 제시합니다:

Windows Forms 애플리케이션을 위한 PDF 렌더링 옵션
옵션 외부 종속성 .NET 지원 상용 라이선스 이미지 출력
ChromePdfRenderer 없음 (자기 포함) .NET 4.6.2 -- .NET 10 예 (체험판 사용 가능) 설정 가능한 DPI에서의 고충실도
Adobe Acrobat COM Adobe Reader/Acrobat 설치됨 Windows .NET Framework 전용 Adobe 라이선스 설치된 버전에 따라 다름
PDFium.NET PDFium 네이티브 바이너리 .NET 5+ BSD (오픈 소스) 좋은 품질, 수동 DPI 제어
GhostScript 래퍼 GhostScript 설치됨 어떤 것이라도 (CLI 또는 COM 통해) AGPL 또는 상업적 좋은 품질, 느린 렌더링

Windows Forms 사용 사례에서 ChromePdfRenderer의 주요 장점은 완전히 자체 포함된다는 것입니다 -- 최종 사용자 기기에 외부 소프트웨어를 설치할 필요가 없습니다. ChromePdfRenderer 라이선스 페이지에서 가격 및 무료 체험판 옵션에 대한 자세한 내용을 확인할 수 있습니다. 그 패키지는 NuGet.org에서 다운로드 통계 및 버전 역사와 함께 찾을 수 있습니다. PDF 사양이 페이지 렌더링을 정의하는 방법에 대한 더 깊은 조망을 위해 ISO가 발행한 ISO 32000-2 PDF 표준은 ChromePdfRenderer 및 기타 렌더러가 구현해야 하는 형식을 설명합니다.

이미지 렌더링을 넘어선 ChromePdfRenderer의 기능에 대한 추가적 맥락을 위해, ChromePdfRenderer 문서 홈은 PDF 생성, HTML-to-PDF 변환, 폼 처리, 디지털 서명 등을 다룹니다.

다음 단계는 무엇입니까?

이 튜토리얼에서 보여준 패턴 -- ToBitmap로 렌더링하고, PictureBox에서 표시하며, 인덱스 기반 제어로 내비게이션 --은 Windows Forms에서 기능적이고 종속성이 없는 PDF 뷰어를 제공합니다. 여기서, 애플리케이션의 요구 사항에 따라 탐구할 가치가 있는 몇 가지 방향이 있습니다.

프로덕션 품질의 뷰어를 위해서는 큰 문서를 효율적으로 처리하기 위해 지연 페이지 렌더링을 고려하고, 주요 뷰어 옆에 스크롤할 수 있는 썸네일 패널을 추가하며, DPI 매개변수에 연결된 줌 컨트롤을 노출하십시오. 문서 관리 애플리케이션을 위해, 뷰어를 ChromePdfRenderer의 텍스트 추출폼 필드 읽기 기능과 결합하여 검색 가능한 문서 인덱스를 구축하십시오.

워크플로우가 프로그래밍 방식으로 PDF를 생성하고 이를 표시하는 것을 포함한다면, ChromePdfRenderer는 또한 HTML to PDF 변환PDF를 처음부터 생성할 수 있도록 지원합니다. 같은 라이브러리가 생성과 보기 모두를 처리합니다.

무료 체험을 시작하여 개발을 위한 워터마크 없는 라이선스 키를 받거나, 완전한 API 레퍼런스를 검토하여 PdfDocument, AnyBitmap 및 지원 렌더링 클래스에서 사용할 수 있는 전체 메서드 집합을 확인하세요. ChromePdfRenderer 예제 갤러리는 C#에서의 일반적인 PDF 작업을 다루는 즉시 실행 가능한 코드 샘플도 보유하고 있습니다.

자주 묻는 질문

C#을 사용하여 Windows Forms PictureBox에 PDF를 표시하는 방법은 무엇입니까?

IronPDF의 ToBitmap 메서드를 사용하여 PDF 페이지를 AnyBitmap 객체로 렌더링하고, 각 페이지를 System.Drawing.Bitmap으로 변환한 후 PictureBox.Image에 할당합니다.

IronPDF는 C#에서 PDF 페이지를 렌더링하기 위해 어떤 메서드를 제공합니까?

IronPDF는 조절 가능한 DPI로 AnyBitmap 객체로 PDF 페이지를 렌더링하는 ToBitmap 메서드를 제공합니다. PictureBox 사용을 위해 변환하려면 ToImage()을 호출하십시오.

PictureBox에서 PDF 페이지를 탐색할 수 있습니까?

예. 렌더링된 페이지 비트맵을 배열에 저장하고 페이지 인덱스 변수를 증가 또는 감소시킵니다. 각 탐색 클릭에서 해당 비트맵을 PictureBox.Image에 할당하십시오.

Windows Forms에서 PDF를 표시할 때 IronPDF를 사용하는 장점은 무엇입니까?

IronPDF는 완전히 독립적이며 추가 소프트웨어 설치가 필요 없습니다. Adobe Acrobat에 의존하지 않고 조절 가능한 DPI 렌더링, 페이지 탐색, 인쇄 및 텍스트 추출을 지원합니다.

IronPDF가 PictureBox에 표시할 수 있도록 다중 페이지 PDF를 처리할 수 있습니까?

예. ToBitmap은 페이지당 하나의 AnyBitmap을 반환합니다. 배열을 저장하고 인덱스로 탐색하거나 ToBitmap(dpi, startPage, endPage) 오버로드를 사용하여 필요에 따라 페이지별로 렌더링하십시오.

Curtis Chau
기술 문서 작성자

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

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

아이언 서포트 팀

저희는 주 5일, 24시간 온라인으로 운영합니다.
채팅
이메일
전화해