如何将pdf文件转换为图像

时间:2014-05-28 07:23:00

标签: c# image pdf

我有一些文件。它的格式是PDF格式。 现在有一个项目,这个项目需要将PDF文件转换为Image。如果PDF是多页,我只需要一个包含所有PDF页面的图像。 我从谷歌得到了一些答案,但有些工具是收费的。

那么,如何用C#解决它? 非常感谢你!

我知道,在C#中使用Acrobat.dll可以解决这个问题,但它必须安装Adobe Acrobat并且它不是免费的。

15 个答案:

答案 0 :(得分:15)

您可以使用Ghostscript将PDF转换为图片。

要使用 .NET 中的 Ghostscript ,您可以查看Ghostscript.NET库(Ghostscript库周围的托管包装器)。

要使用 Ghostscript.NET PDF 制作图片,请查看RasterizerSample

要将多个图像合并到单个图像中,请查看此示例:http://www.niteshluharuka.com/2012/08/combine-several-images-to-form-a-single-image-using-c/#

答案 1 :(得分:13)

以下主题适合您的请求。 converting pdf file to an jpeg image

一种解决方案是使用第三方库。 ImageMagick非常受欢迎,也可以免费使用。你可以为它获得一个.NET包装器here。原始的ImageMagick下载页面为here

你也可以看看这个帖子: how to open a page from a pdf file in pictureBox in C#

如果您使用this process to convert a PDF to tiff,则可以使用此类从tiff中检索位图。

public class TiffImage
{
    private string myPath;
    private Guid myGuid;
    private FrameDimension myDimension;
    public ArrayList myImages = new ArrayList();
    private int myPageCount;
    private Bitmap myBMP;

    public TiffImage(string path)
    {
        MemoryStream ms;
        Image myImage;

        myPath = path;
        FileStream fs = new FileStream(myPath, FileMode.Open);
        myImage = Image.FromStream(fs);
        myGuid = myImage.FrameDimensionsList[0];
        myDimension = new FrameDimension(myGuid);
        myPageCount = myImage.GetFrameCount(myDimension);
        for (int i = 0; i < myPageCount; i++)
        {
            ms = new MemoryStream();
            myImage.SelectActiveFrame(myDimension, i);
            myImage.Save(ms, ImageFormat.Bmp);
            myBMP = new Bitmap(ms);
            myImages.Add(myBMP);
            ms.Close();
        }
        fs.Close();
    }
}

像这样使用它:

private void button1_Click(object sender, EventArgs e)
{
    TiffImage myTiff = new TiffImage("D:\\Some.tif");
    //imageBox is a PictureBox control, and the [] operators pass back
    //the Bitmap stored at that position in the myImages ArrayList in the TiffImage
    this.pictureBox1.Image = (Bitmap)myTiff.myImages[0];
    this.pictureBox2.Image = (Bitmap)myTiff.myImages[1];
    this.pictureBox3.Image = (Bitmap)myTiff.myImages[2];
}

答案 2 :(得分:5)

对于如何在C#中将PDF转换为图像的问题,2018仍然没有简单的答案;许多库使用GhostScript licensed under AGPL,在大多数情况下,生产使用需要昂贵的商业许可证。

好的选择可能是使用具有GPL许可的poppler'pdftoppm'实用程序;它可以在C#中用作System.Diagnostics.Process执行的命令行工具。 Poppler工具在Linux世界中是众所周知的,但也可以使用windows build

如果您不想自己集成pdftoppm,可以使用我的PdfRenderer poppler wrapper(支持经典的.NET Framework和.NET Core) - 它不是免费的,但定价非常实惠。

答案 3 :(得分:4)

我在PDFiumSharp 2.1类库中使用了ImageSharp.NET Standard

/// <summary>
/// Saves a thumbnail (jpg) to the same folder as the PDF file, using dimensions 300x423,
/// which corresponds to the aspect ratio of 'A' paper sizes like A4 (ratio h/w=sqrt(2))
/// </summary>
/// <param name="pdfPath">Source path of the pdf file.</param>
/// <param name="thumbnailPath">Target path of the thumbnail file.</param>
/// <param name="width"></param>
/// <param name="height"></param>
public static void SaveThumbnail(string pdfPath, string thumbnailPath = "", int width = 300, int height = 423)
{
    using var pdfDocument = new PdfDocument(pdfPath);
    var firstPage = pdfDocument.Pages[0];

    using var pageBitmap = new PDFiumBitmap(width, height, true);

    firstPage.Render(pageBitmap);

    var imageJpgPath = string.IsNullOrWhiteSpace(thumbnailPath)
        ? Path.ChangeExtension(pdfPath, "jpg")
        : thumbnailPath;
    var image = Image.Load(pageBitmap.AsBmpStream());

    // Set the background to white, otherwise it's black. https://github.com/SixLabors/ImageSharp/issues/355#issuecomment-333133991
    image.Mutate(x => x.BackgroundColor(Rgba32.White));

    image.Save(imageJpgPath, new JpegEncoder());
}

答案 4 :(得分:3)

关于PDFiumSharp:经过详细阐述,我能够从PDF解决方案中创建PNG文件。

这是我的代码:

using PDFiumSharp;
using System.Collections.Generic;
using System.Drawing;
using System.IO;

public class Program
{
    static public void Main(String[] args)
    {
        var renderfoo = new Renderfoo()
        renderfoo.RenderPDFAsImages(@"C:\Temp\example.pdf", @"C:\temp");
    }
}



public class Renderfoo
{

    public void RenderPDFAsImages(string Inputfile, string OutputFolder)
    {
        string fileName = Path.GetFileNameWithoutExtension(Inputfile);

        using (PDFiumSharp.PdfDocument doc = new PDFiumSharp.PdfDocument(Inputfile))
        {
            for (int i = 0; i < doc.Pages.Count; i++)
            {
                var page = doc.Pages[i];
                using (var bitmap = new System.Drawing.Bitmap((int)page.Width, (int)page.Height))
                {
                    var grahpics = Graphics.FromImage(bitmap);
                    grahpics.Clear(Color.White);
                    page.Render(bitmap);
                    var targetFile = Path.Combine(OutputFolder, fileName + "_" + i + ".png");
                    bitmap.Save(targetFile);
                }
            }
        }
    }

}

对于初学者,您需要执行以下步骤来启动并运行PDFium包装器:

  • 通过在Visual Studio中右键单击,为两个tt文件运行自定义代码工具
  • 编译GDIPlus项目
  • 将已编译的程序集(从GDIPlus项目中)复制到您的项目中
  • 同时引用项目中的 PDFiumSharp PDFiumsharp.GdiPlus 程序集

  • 确保在项目输出目录中都找到了pdfium_x64.dll和/或pdfium_x86.dll。

答案 5 :(得分:2)

此nuget软件包: https://www.nuget.org/packages/Pdf2Png/

是免费提供的,仅受非常开放的MIT许可证保护。

我已经测试了一下,这是使它将pdf转换为图像的代码。 (它将图像保存在调试文件夹中。)

using cs_pdf_to_image;
using PdfToImage;

    private void BtnConvert_Click(object sender, EventArgs e)
    {
        if(openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            try
            {
                string PdfFile = openFileDialog1.FileName;
                string PngFile = "Convert.png";
                List<string> Conversion = cs_pdf_to_image.Pdf2Image.Convert(PdfFile, PngFile);
                Bitmap Output = new Bitmap(PngFile);
                PbConversion.Image = Output;
            }
            catch(Exception E)
            {
                MessageBox.Show(E.Message);
            }
        }
    }

答案 6 :(得分:0)

(免责声明我在Software Siglo XXI上使用此组件)

您可以使用 Super Pdf2Image Converter 生成TIFF多页文件,其中包含PDF中高分辨率的所有渲染页面。它适用于32位和64位,非常便宜和有效。我建议你试一试。

只需一行代码......

GetImage(outputFileName, firstPage, lastPage, resolution, imageFormat)

Converts specifies pages to image and save them to outputFileName (tiff allows multi-page or creates several files)

您可以在此处查看:http://softwaresigloxxi.com/SuperPdf2ImageConverter.html

答案 7 :(得分:0)

在Google Chrome浏览器中使用的称为PDFium的PDF引擎根据“ BSD 3条款”许可是开源的。我相信,当用于商业产品时,这可以重新分配。

有一个名为PdfiumViewernuget)的.NET包装器,在我尝试过的范围内,它可以很好地工作。它受Apache许可,也允许重新分发。

(请注意,这与需要商业许可的https://pdfium.patagames.com/不同)。

(还有另一个PDFium .NET包装器PDFiumSharp,但我尚未对其进行评估。)

IMO到目前为止,这可能是开源(像啤酒一样免费)PDF库的最佳选择,它不会对使用它们的软件的封闭源/商业性质造成限制。据我所知,我认为答案中的其他内容都不能满足该标准。

答案 8 :(得分:0)

使用tanPDF。它是准确的,并且仅为商业用途的Ghostscript价格的一小部分。还有ImageMagick,因为这需要Ghostscript。

tanPDF使用Skia,因此,如果您想要一张包含所有页面的图像,请将每页的SKImage绘制到SKCanvas上。

免责声明:我是作者。

答案 9 :(得分:0)

使用Android默认库(例如AppCompat),您可以将所有PDF页面转换为图像。这种方法非常快速且经过优化。 下面的代码用于获取PDF页面的单独图像。可能对您有帮助,因为它非常快捷。

ParcelFileDescriptor fileDescriptor = ParcelFileDescriptor.open(new File("pdfFilePath.pdf"), MODE_READ_ONLY);
    PdfRenderer renderer = new PdfRenderer(fileDescriptor);
    final int pageCount = renderer.getPageCount();
    for (int i = 0; i < pageCount; i++) {
        PdfRenderer.Page page = renderer.openPage(i);
        Bitmap bitmap = Bitmap.createBitmap(page.getWidth(), page.getHeight(),Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawColor(Color.WHITE);
        canvas.drawBitmap(bitmap, 0, 0, null);
        page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
        page.close();

        if (bitmap == null)
            return null;

        if (bitmapIsBlankOrWhite(bitmap))
            return null;

        String root = Environment.getExternalStorageDirectory().toString();
        File file = new File(root + filename + ".png");

        if (file.exists()) file.delete();
        try {
            FileOutputStream out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            Log.v("Saved Image - ", file.getAbsolutePath());
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

================================================ ========

private static boolean bitmapIsBlankOrWhite(Bitmap bitmap) {
    if (bitmap == null)
        return true;

    int w = bitmap.getWidth();
    int h = bitmap.getHeight();
    for (int i =  0; i < w; i++) {
        for (int j = 0; j < h; j++) {
            int pixel =  bitmap.getPixel(i, j);
            if (pixel != Color.WHITE) {
                return false;
            }
        }
    }
    return true;
}

答案 10 :(得分:0)

我在SourceForge碰到了这个项目。在我看来,它仍然很活跃。

  1. PDF convert to JPEG at SourceForge
  2. Developer's site

我的两分钱。

答案 11 :(得分:0)

Apache PDFBox对我也很好。

与命令行工具一起使用:

javar -jar pdfbox-app-2.0.19.jar PDFToImage -quality 1.0  -dpi 150 -prefix out_dir/page -format png

答案 12 :(得分:0)

有一个免费的nuget程序包(Pdf2Image),它允许将pdf页面提取到jpg文件或图像集合(列表)中只需一行即可

        string file = "c:\\tmp\\test.pdf";

        List<System.Drawing.Image> images = PdfSplitter.GetImages(file, PdfSplitter.Scale.High);

        PdfSplitter.WriteImages(file, "c:\\tmp", PdfSplitter.Scale.High, PdfSplitter.CompressionLevel.Medium);

所有源代码也可以在github Pdf2Image

上找到。

答案 13 :(得分:0)

https://www.codeproject.com/articles/317700/convert-a-pdf-into-a-series-of-images-using-csharp

我发现此GhostScript包装程序可以像魅力一样工作,将PDF逐页转换为PNG。

用法:

string pdf_filename = @"C:\TEMP\test.pdf";            
var pdf2Image = new Cyotek.GhostScript.PdfConversion.Pdf2Image(pdf_filename);
for (var page = 1; page < pdf2Image.PageCount; page++)
{
    string png_filename = @"C:\TEMP\test" + page + ".png";
    pdf2Image.ConvertPdfPageToImage(png_filename, page);
}

基于GhostScript构建,显然对于商业应用而言,许可问题仍然存在。

答案 14 :(得分:0)

在 dotnet 核心中搜索适用于 Windows 和 Linux 的强大且免费的解决方案让我找到了 https://github.com/Dtronix/PDFiumCorehttps://github.com/GowenGit/docnet。由于 PDFiumCore 使用更新版本的 Pdfium(这似乎是使用 pdf 库的关键点),因此我最终使用了它。

注意:如果您想在 Linux 上使用它,您应该按照 https://stackoverflow.com/a/59252639/6339469 的建议安装“libgdiplus”。

这是一个简单的单线程代码:

var pageIndex = 0;
var scale = 2;

fpdfview.FPDF_InitLibrary();

var document = fpdfview.FPDF_LoadDocument("test.pdf", null);

var page = fpdfview.FPDF_LoadPage(document, pageIndex);

var size = new FS_SIZEF_();
fpdfview.FPDF_GetPageSizeByIndexF(document, 0, size);

var width = (int)Math.Round(size.Width * scale);
var height = (int)Math.Round(size.Height * scale);

var bitmap = fpdfview.FPDFBitmapCreateEx(
    width,
    height,
    4, // BGRA
    IntPtr.Zero,
    0);

fpdfview.FPDFBitmapFillRect(bitmap, 0, 0, width, height, (uint)Color.White.ToArgb());

// |          | a b 0 |
// | matrix = | c d 0 |
// |          | e f 1 |
using var matrix = new FS_MATRIX_();
using var clipping = new FS_RECTF_();

matrix.A = scale;
matrix.B = 0;
matrix.C = 0;
matrix.D = scale;
matrix.E = 0;
matrix.F = 0;

clipping.Left = 0;
clipping.Right = width;
clipping.Bottom = 0;
clipping.Top = height;

fpdfview.FPDF_RenderPageBitmapWithMatrix(bitmap, page, matrix, clipping, (int)RenderFlags.RenderAnnotations);

var bitmapImage = new Bitmap(
    width,
    height,
    fpdfview.FPDFBitmapGetStride(bitmap),
    PixelFormat.Format32bppArgb,
    fpdfview.FPDFBitmapGetBuffer(bitmap));

bitmapImage.Save("test.jpg", ImageFormat.Jpeg);

对于线程安全的实现,请参见: https://github.com/hmdhasani/DtronixPdf/blob/master/src/DtronixPdfBenchmark/Program.cs