从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框架。

Acrobat SDK结合完整版本的Adobe Acrobat,公开了一个COM对象库(可惜免费的Adobe Reader不公开COM接口),可用于操作和访问PDF信息。通过COM Interop使用这些COM对象,加载PDF文档,获取第一页并将该页面渲染到剪贴板。然后,使用.NET框架,将其复制到位图,缩放并合并图像,并将结果保存为GIF或PNG文件。

安装Adobe Acrobat后,使用regedit.exe并在HKEY_CLASSES_ROOT下查找名为AcroExch.PDDoc的条目。

注册表显示AcroExch.PDDDoc条目

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具有明显的优势:

  • 您不需要在系统上安装Adobe Acrobat即可处理PDF文件。
  • 使用Aspose.PDF for .NET相较于Acrobat自动化更简单易懂。

如果我们需要将PDF页面转换为JPEG,Aspose.PDF.Devices命名空间提供了一个名为JpegDevice的类,用于将PDF页面渲染为JPEG图像。请查看以下代码片段。

// 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);
                }
            }
        }
    }
}