PDF에서 썸네일 이미지 생성

Acrobat 애플리케이션 간 통신 API를 사용한 애플리케이션 개발

Acrobat API는 Acrobat 애플리케이션 간 통신(IAC) 객체를 사용하는 두 개의 뚜렷한 레이어로 구성되어 있다고 생각할 수 있습니다:

  • Acrobat 애플리케이션(AV) 레이어. AV 레이어는 문서가 어떻게 표시되는지를 제어할 수 있게 해줍니다. 예를 들어, 문서 객체의 뷰는 Acrobat과 연결된 레이어에 존재합니다.
  • 휴대용 문서(PD) 레이어. PD 레이어는 페이지와 같은 문서 내의 정보에 접근할 수 있게 해줍니다. PD 레이어에서 PDF 문서의 기본 조작을 수행할 수 있으며, 페이지를 삭제, 이동 또는 교체하거나 주석 속성을 변경할 수 있습니다. 또한 PDF 페이지를 인쇄하고, 텍스트를 선택하고, 조작된 텍스트에 접근하며, 썸네일을 생성하거나 삭제할 수 있습니다.

우리의 의도는 PDF 페이지를 썸네일 이미지로 변환하는 것이므로 IAC에 더 집중하고 있습니다. IAC API에는 PDDoc, PDPage, PDAnnot 등과 같은 객체가 포함되어 있어 사용자가 휴대용 문서(PD) 레이어를 다룰 수 있게 해줍니다. 다음 코드 샘플은 폴더를 스캔하고 PDF 페이지를 썸네일 이미지로 변환합니다. Acrobat SDK를 사용하면 PDF 메타데이터를 읽고 문서의 페이지 수를 가져올 수도 있습니다.

Acrobat 접근법

각 문서에 대한 썸네일 이미지를 생성하기 위해 Adobe Acrobat 7.0 SDK와 Microsoft .NET 2.0 Framework를 사용했습니다.

Acrobat SDK는 Adobe Acrobat의 전체 버전과 결합되어 COM 객체 라이브러리를 노출합니다(안타깝게도 무료 Adobe Reader는 COM 인터페이스를 노출하지 않습니다). 이러한 COM 객체를 COM Interop을 통해 사용하여 PDF 문서를 로드하고 첫 페이지를 가져와 클립보드에 렌더링합니다. 그런 다음 .NET Framework를 사용하여 이를 비트맵으로 복사하고 이미지를 스케일링 및 결합하여 결과를 GIF 또는 PNG 파일로 저장합니다.

Adobe Acrobat이 설치되면 regedit.exe를 사용하여 HKEY_CLASSES_ROOT에서 AcroExch.PDDoc이라는 항목을 찾습니다.

AcroExch.PDDoc 항목을 보여주는 레지스트리

todo:image_alt_text

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void GenerateThumbnailImagesFromPDF()
{
    // Acrobat objects
    Acrobat.CAcroPDDoc pdfDoc;
    Acrobat.CAcroPDPage pdfPage;
    Acrobat.CAcroRect pdfRect;
    Acrobat.CAcroPoint pdfPoint;

    AppSettingsReader appSettings = new AppSettingsReader();
    string pdfInputPath = appSettings.GetValue("pdfInputPath", typeof(string)).ToString();
    string pngOutputPath = appSettings.GetValue("pngOutputPath", typeof(string)).ToString();
    string templatePortraitFile = Application.StartupPath + @"\pdftemplate_portrait.gif";
    string templateLandscapeFile = Application.StartupPath + @"\pdftemplate_landscape.gif";

    // Get list of files to process from the input path
    string[] files = Directory.GetFiles(pdfInputPath, "*.pdf");

    for (int n = 0; n < files.Length; n++)
    {
        string inputFile = files[n];
        string outputFile = Path.Combine(pngOutputPath, Path.GetFileNameWithoutExtension(inputFile) + ".png");

        // Create PDF document
        pdfDoc = (Acrobat.CAcroPDDoc)Microsoft.VisualBasic.Interaction.CreateObject("AcroExch.PDDoc", "");

        if (pdfDoc.Open(inputFile) == 0)
        {
            throw new FileNotFoundException($"Unable to open PDF file: {inputFile}");
        }

        int pageCount = pdfDoc.GetNumPages();
        pdfPage = (Acrobat.CAcroPDPage)pdfDoc.AcquirePage(0);
        pdfPoint = (Acrobat.CAcroPoint)pdfPage.GetSize();

        pdfRect = (Acrobat.CAcroRect)Microsoft.VisualBasic.Interaction.CreateObject("AcroExch.Rect", "");
        pdfRect.Left = 0;
        pdfRect.right = pdfPoint.x;
        pdfRect.Top = 0;
        pdfRect.bottom = pdfPoint.y;

        pdfPage.CopyToClipboard(pdfRect, 0, 0, 100);
        IDataObject clipboardData = Clipboard.GetDataObject();

        if (clipboardData.GetDataPresent(DataFormats.Bitmap))
        {
            Bitmap pdfBitmap = (Bitmap)clipboardData.GetData(DataFormats.Bitmap);

            int thumbnailWidth = 45;
            int thumbnailHeight = 59;
            string templateFile = pdfPoint.x < pdfPoint.y ? templatePortraitFile : templateLandscapeFile;

            if (pdfPoint.x > pdfPoint.y)
            {
                // Swap width and height for landscape orientation
                (thumbnailWidth, thumbnailHeight) = (thumbnailHeight, thumbnailWidth);
            }

            Bitmap templateBitmap = new Bitmap(templateFile);
            Image pdfImage = pdfBitmap.GetThumbnailImage(thumbnailWidth, thumbnailHeight, null, IntPtr.Zero);

            Bitmap thumbnailBitmap = new Bitmap(thumbnailWidth + 7, thumbnailHeight + 7, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            templateBitmap.MakeTransparent();

            using (Graphics thumbnailGraphics = Graphics.FromImage(thumbnailBitmap))
            {
                thumbnailGraphics.DrawImage(pdfImage, 2, 2, thumbnailWidth, thumbnailHeight);
                thumbnailGraphics.DrawImage(templateBitmap, 0, 0);
                thumbnailBitmap.Save(outputFile, System.Drawing.Imaging.ImageFormat.Png);
            }

            Console.WriteLine("Generated thumbnail: {0}", outputFile);

            pdfDoc.Close();
            Marshal.ReleaseComObject(pdfPage);
            Marshal.ReleaseComObject(pdfRect);
            Marshal.ReleaseComObject(pdfDoc);
        }
    }
}

Aspose.PDF for .NET 접근법

Aspose.PDF for .NET는 PDF 문서를 다루는 데 광범위한 지원을 제공합니다. 또한 PDF 문서의 페이지를 다양한 이미지 형식으로 변환하는 기능을 지원합니다. 위에서 설명한 기능은 Aspose.PDF for .NET를 사용하여 쉽게 달성할 수 있습니다.

Aspose.PDF는 뚜렷한 이점이 있습니다:

  • PDF 파일을 작업하기 위해 시스템에 Adobe Acrobat을 설치할 필요가 없습니다.
  • Aspose.PDF for .NET는 Acrobat Automation에 비해 간단하고 이해하기 쉽습니다.

PDF 페이지를 JPEG로 변환해야 하는 경우, Aspose.PDF.Devices 네임스페이스는 PDF 페이지를 JPEG 이미지로 렌더링하기 위한 JpegDevice라는 클래스를 제공합니다. 다음 코드 스니펫을 살펴보세요.

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void GenerateThumbnailImagesFromPDF()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_Images();

    // Retrieve names of all the PDF files in a particular directory
    string[] fileEntries = Directory.GetFiles(dataDir, "*.pdf");

    // Iterate through all the files entries in array
    for (int counter = 0; counter < fileEntries.Length; counter++)
    {
        // Open PDF document
        using (var document = new Aspose.Pdf.Document(fileEntries[counter]))
        {
            for (int pageCount = 1; pageCount <= document.Pages.Count; pageCount++)
            {
                using (FileStream imageStream = new FileStream(dataDir + @"\Thumbanils" + counter.ToString() + "_" + pageCount + ".jpg", FileMode.Create))
                {
                    var resolution = new Aspose.Pdf.Devices.Resolution(300);
                    var jpegDevice = new Aspose.Pdf.Devices.JpegDevice(45, 59, resolution, 100);
                    // Convert a particular page and save the image to stream
                    jpegDevice.Process(document.Pages[pageCount], imageStream);
                }
            }
        }
    }
}