【问题标题】:Merging PDFs and converting PDF to PNG image in .NET Core 2.0在 .NET Core 2.0 中合并 PDF 并将 PDF 转换为 PNG 图像
【发布时间】:2018-09-04 17:28:50
【问题描述】:

我正在寻找可以支持将 pdf 合并为一个并将合并的 pdf 转换为一个 .PNG 图像文件的第三方 .dll。

我知道 Ghostscript 或 pdfsharp 支持 .NET 框架,但不支持 .NET core 2.0 框架。

如果有人可以请建议任何第三方 dll,它可以合并所有 PDF 并将合并的 pdf 转换为 .NET core 2.0 中的 PNG 图像。

有任何帮助或建议来实现这一要求吗?

【问题讨论】:

  • itext7 pdf to image的可能重复
  • 你的问题跑题了。但是,仅仅因为一个库不是专门为 .NET Core 构建的,并不意味着您不能继续使用它。我建议首先尝试参考这些库,看看你能走多远。一切都可以正常工作。
  • stackoverflow.com/q/37809019/2309376 显示如何转换为图像。您也可以使用同一个库 iText7 来合并 PDF 的
  • itext 7 不能解决我的问题,因为 itext 7 不支持将合并的 pdf 转换为 PNG 图像,而且我猜 itext 7 不支持 .NET core 2.0
  • Chris Pratt 感谢您的回复 :) ...我尝试安装 ghostscript 并引用那些在运行时出错的库 :(

标签: c# asp.net-core .net-core asp.net-core-mvc


【解决方案1】:

你可以使用iTextSharp.LGPLv2.Core 来合并pdf文件,效果很好。请check this tutorial。它也支持 .NETStandard。

    using System;
    using System.Collections.Generic;
    using System.IO;
    using iTextSharp.text;
    using iTextSharp.text.pdf;

    namespace HelveticSolutions.PdfLibrary
    {
      public static class PdfMerger
      {
        /// <summary>
        /// Merge pdf files.
        /// </summary>
        /// <param name="sourceFiles">PDF files being merged.</param>
        /// <returns></returns>
        public static byte[] MergeFiles(List<byte[]> sourceFiles)
        {
          Document document = new Document();
          using (MemoryStream ms = new MemoryStream())
          {
            PdfCopy copy = new PdfCopy(document, ms);
            document.Open();
            int documentPageCounter = 0;

            // Iterate through all pdf documents
            for (int fileCounter = 0; fileCounter < sourceFiles.Count; fileCounter++)
            {
              // Create pdf reader
              PdfReader reader = new PdfReader(sourceFiles[fileCounter]);
              int numberOfPages = reader.NumberOfPages;

              // Iterate through all pages
              for (int currentPageIndex = 1; currentPageIndex <= numberOfPages; currentPageIndex++)
              {
                documentPageCounter++;
                PdfImportedPage importedPage = copy.GetImportedPage(reader, currentPageIndex);
                PdfCopy.PageStamp pageStamp = copy.CreatePageStamp(importedPage);

                // Write header
                ColumnText.ShowTextAligned(pageStamp.GetOverContent(), Element.ALIGN_CENTER,
                    new Phrase("PDF Merger by Helvetic Solutions"), importedPage.Width / 2, importedPage.Height - 30,
                    importedPage.Width < importedPage.Height ? 0 : 1);

                // Write footer
                ColumnText.ShowTextAligned(pageStamp.GetOverContent(), Element.ALIGN_CENTER,
                    new Phrase(String.Format("Page {0}", documentPageCounter)), importedPage.Width / 2, 30,
                    importedPage.Width < importedPage.Height ? 0 : 1);

                pageStamp.AlterContents();

                copy.AddPage(importedPage);
              }

              copy.FreeReader(reader);
              reader.Close();
            }

            document.Close();
            return ms.GetBuffer();
          }
        }
      }
    }

【讨论】:

    【解决方案2】:

    我自己最近一直在为此苦苦挣扎,找不到适合我需要的库,所以我围绕 PDFium 编写了一个 C# 包装器,它具有 BSD 3-clause 许可证,并且我的包装器代码在 MIT 下发布,所以你可以使用NuGet 包,也可以自己直接使用代码。可以在这里找到回购docnet

    【讨论】:

      【解决方案3】:

      DynamicPDF Rasterizer(NuGet Pakage ID:ceTe.DynamicDPF.Rasterizer.NET)将 PDF 转换为 PNG 并在 .NET Core 上运行。您还可以使用 DynamicPDF Merger(NuGet 包 ID:ceTe.DynamicPDF.CoreSuite.NET)来合并 PDF。这是一个例子:

      //Merging existing PDFs using DynamicPDF Merger for .NET product.
      MergeDocument mergeDocument = new MergeDocument();
      mergeDocument.Append(@"D:\temporary\DocumentB.pdf");
      mergeDocument.Append(@"D:\temporary\DocumentC.pdf");
      mergeDocument.Append(@"D:\temporary\DocumentD.pdf");
       
      //Draw the merged output into byte array or save it to disk (by specifying the file path).
      byte[] byteData = mergeDocument.Draw();
       
      //Convert the merged PDF into PMG image format using DynamicPDF Rasterizer for .NET product.
      InputPdf pdfData = new InputPdf(byteData);
      PdfRasterizer rastObj = new PdfRasterizer(pdfData);
      rastObj.Draw(@"C:\temp\MyImage.png", ImageFormat.Png, ImageSize.Dpi150);

      有关 Rasterizer 输出格式的更多信息,请参见此处:

      http://docs.dynamicpdf.com/NET_Help_Library_19_08/DynamicPDFRasterizerProgrammingWithOutputImageFormat.html

      可在此处找到有关将 DynamicPDF Merger 和 Rasterizer 部署到 .NET Core 2.0 的更多信息:

      http://docs.dynamicpdf.com/NET_Help_Library_19_08/DynamicPDFRasterizerProgrammingWithReferencingTheAssembly.html

      http://docs.dynamicpdf.com/NET_Help_Library_19_08/Merger%20Referencing%20the%20Assembly%20and%20Deployment.html

      【讨论】:

        【解决方案4】:

        我只是回答有关在 .NET Core 3.1 中呈现 PDF 并将其转换为图像的部分,这需要几天时间才能弄清楚。我最终使用 phuldr 的 Docnet.Core 来获取图像字节并使用 Magick.NET-Q16-AnyCpu 将其保存到图像文件中。

        需要做一些额外的工作来将图像字节重新排列为 RGBA 顺序并将透明像素转换为特定颜色(在我的情况下为白色)。这是我的代码,以防万一:

        public MemoryStream PdfToImage(byte[] pdfBytes /* the PDF file bytes */)
        {
            MemoryStream memoryStream = new MemoryStream();
            MagickImage imgBackdrop;
            MagickColor backdropColor = MagickColors.White; // replace transparent pixels with this color 
            int pdfPageNum = 0; // first page is 0
        
            using (IDocLib pdfLibrary = DocLib.Instance)
            {
                using (var docReader = pdfLibrary.GetDocReader(pdfBytes, new PageDimensions(1.0d)))
                {
                    using (var pageReader = docReader.GetPageReader(pdfPageNum))
                    {
                        var rawBytes = pageReader.GetImage(); // Returns image bytes as B-G-R-A ordered list.
                        rawBytes = RearrangeBytesToRGBA(rawBytes);
                        var width = pageReader.GetPageWidth();
                        var height = pageReader.GetPageHeight();
        
                        // specify that we are reading a byte array of colors in R-G-B-A order.
                        PixelReadSettings pixelReadSettings = new PixelReadSettings(width, height, StorageType.Char, PixelMapping.RGBA);
                        using (MagickImage imgPdfOverlay = new MagickImage(rawBytes, pixelReadSettings))
                        {
                            // turn transparent pixels into backdrop color using composite: http://www.imagemagick.org/Usage/compose/#compose
                            imgBackdrop = new MagickImage(backdropColor, width, height);                            
                            imgBackdrop.Composite(imgPdfOverlay, CompositeOperator.Over);
                        }
                    }
                }
            }
        
            
            imgBackdrop.Write(memoryStream, MagickFormat.Png);
            imgBackdrop.Dispose();
            memoryStream.Position = 0;
            return memoryStream;
        }
        
        private byte[] RearrangeBytesToRGBA(byte[] BGRABytes)
        {
            var max = BGRABytes.Length;
            var RGBABytes = new byte[max];
            var idx = 0;
            byte r;
            byte g;
            byte b;
            byte a;
            while (idx < max)
            {
                // get colors in original order: B G R A
                b = BGRABytes[idx];
                g = BGRABytes[idx + 1];
                r = BGRABytes[idx + 2];
                a = BGRABytes[idx + 3];
        
                // re-arrange to be in new order: R G B A
                RGBABytes[idx] = r;
                RGBABytes[idx + 1] = g;
                RGBABytes[idx + 2] = b;
                RGBABytes[idx + 3] = a;
        
                idx += 4;
            }
            return RGBABytes;
        }
        

        【讨论】:

        • 嗨!您是否在 pdfLibrary.GetDocReader(..) 上遇到任何错误?我正在运行一个异常:“无法打开文档”
        • 我不记得在 pdfLibrary.GetDocReader() 上遇到过问题。我通过流读取 pdfBytes,然后在调用 GetDocReader 之前关闭流。我猜这与您创建 pdfBytes 的方式有关...
        【解决方案5】:

        看看Docotic.Pdf library。这个库支持.NET Core,没有任何依赖和不安全的代码。

        Docotic 的 PDF 到图像渲染器不依赖于 GDI+ (System.Drawing)。这对于在 ASP.NET 上下文或 Linux 上可靠运行代码非常重要。

        合并 PDF 文档:

        public void MergeDocuments(string firstPath, string secondPath)
        {
            using (var pdf = new PdfDocument(firstPath))
            {
                pdf.Append(secondPath); // or append stream or byte array
        
                pdf.ReplaceDuplicateObjects(); // useful when merged files contain common objects like fonts and images
        
                pdf.Save("merged.pdf");
            }
        }
        

        将 PDF 页面转换为 PNG 图像:

        using (var pdf = new PdfDocument(@"merged.pdf"))
        {
            PdfDrawOptions options = PdfDrawOptions.Create();
            options.Compression = ImageCompressionOptions.CreatePng();
            options.BackgroundColor = new PdfRgbColor(255, 255, 255);
            options.HorizontalResolution = 600;
            options.VerticalResolution = 600;
        
            pdf.Pages[0].Save("result.png", options);
        }
        

        More samples for PDF to image conversion

        您提到了将合并的 PDF 文档转换为单个 PNG 图像。 PNG 不支持多帧图像 (more detail)。所以只能做到以下几点:

        1. 将所有 PDF 文档页面合并到单个页面
        2. 如上所述呈现此页面

        这是本案例的示例(将 2 页合并为一页并另存为 PNG):

        using (var other = new PdfDocument(@"merged.pdf"))
        {
            using (var pdf = new PdfDocument())
            {
                PdfXObject firstXObject = pdf.CreateXObject(other.Pages[0]);
                PdfXObject secondXObject = pdf.CreateXObject(other.Pages[1]);
        
                PdfPage page = pdf.Pages[0];
                double halfOfPage = page.Width / 2;
                page.Canvas.DrawXObject(firstXObject, 0, 0, halfOfPage, 400, 0);
                page.Canvas.DrawXObject(secondXObject, halfOfPage, 0, halfOfPage, 400, 0);
        
                PdfDrawOptions options = PdfDrawOptions.Create();
                options.BackgroundColor = new PdfRgbColor(255, 255, 255);
                page.Save("result.png", options);
            }
        }
        

        【讨论】:

        • 仅供参考,此产品需要商业使用许可证
        猜你喜欢
        • 1970-01-01
        • 2015-09-20
        • 2017-04-15
        • 2013-12-11
        • 2014-12-23
        • 1970-01-01
        • 2019-08-29
        • 1970-01-01
        • 2023-01-19
        相关资源
        最近更新 更多