如何将PDF文件转换为图像
本文关键字:转换 图像 文件 PDF | 更新日期: 2023-09-27 18:05:34
我需要将PDF文件转换为图像。如果PDF文件是多页,我只需要一个包含所有PDF页面的图像。
是否有像Acrobat产品那样不收费的开源解决方案?
将PDF文件转换为JPEG图像的线程适合您的请求。
一个解决方案是使用第三方库。ImageMagick是一个非常受欢迎的免费软件。您可以在这里获得它的. net包装器。原始的ImageMagick下载页面在这里。
- 使用Solid Framework将PDF页面转换为图像文件使用Solid Framework将PDF页面转换为图像文件(死链接,删除的文档可在Internet Archive中找到)
- 将PDF转换为JPG通用文档转换器
- 将PDF转换为JPG图像的6种方法
你也可以看一下线程"如何在c#中的pictureBox中打开pdf文件".
如果您使用此过程将PDF转换为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];
}
您可以使用Ghostscript将PDF转换为图像。
从使用Ghostscript。. NET你可以看看Ghostscript。. NET库(围绕Ghostscript库的托管包装器)。
使用Ghostscript从PDF生成图像。. NET,看看RasterizerSample。要将多个图像合并为单个图像,请查看此示例:http://www.niteshluharuka.com/2012/08/combine-several-images-to-form-a-single-image-using-c/#
至于2018年,如何在c#中将PDF文档转换为图像的问题仍然没有一个简单的答案;许多库使用AGPL许可的Ghostscript,在大多数情况下,生产使用需要昂贵的商业许可证。
一个好的选择可能是使用流行的'pdftoppm'实用程序,它具有GPL许可证;它可以在c#中作为命令行工具使用System.Diagnostics.Process。流行的工具在Linux世界中是众所周知的,但windows版本也可用。
如果你不想自己集成pdftoppm,你可以使用我的PdfRenderer流行的包装器(支持经典的。net框架和。net Core) -它不是免费的,但价格非常实惠。
我在。net标准2.1类库中使用了PDFiumSharp和imagessharp。
/// <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());
}
在Windows和Linux上搜索一个强大而免费的解决方案,我找到了https://github.com/Dtronix/PDFiumCore和https://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
在Google Chrome中使用的PDF引擎,称为PDFium,是在"BSD 3-clause"下开源的。许可证。我相信在商业产品中使用时允许再分发。
它有一个. net包装器称为PdfiumViewer (NuGet),它在我尝试过的程度上工作得很好。它是在Apache许可下的,它也允许再分发。
(注意,这与需要商业许可的https://pdfium.patagames.com/不同)
(有另一个PDFium . net包装器,PDFiumSharp,但我还没有评估它)
在我看来,到目前为止,这可能是开源(免费的)PDF库的最佳选择,以完成而不是对使用它们的软件的闭源/商业性质进行限制的工作。
关于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 中右键单击Custom Code工具来运行这两个tt文件
- 编译GDIPlus项目
- 将编译后的程序集(从GDIPlus项目)复制到您的项目
同时引用PDFiumSharp和PDFiumSharp。GdiPlus程序集
确保pdfium_x64.dll和/或pdfium_x86.dll都在您的项目输出目录中。
您可以选择免费软件。Pdf2Png MIT许可证。在nuget中找到这些名字。
var dd = System.IO.File.ReadAllBytes("pdffile.pdf");
byte[] pngByte = Freeware.Pdf2Png.Convert(dd, 1);
System.IO.File.WriteAllBytes(Path.Combine(@"C:'temp", "dd.png"), pngByte );
NuGet包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);
}
}
}
Apache PDFBox也很适合我。
使用命令行工具:
javar -jar pdfbox-app-2.0.19.jar PDFToImage -quality 1.0 -dpi 150 -prefix out_dir/page -format png
有一个免费的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
使用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;
}
我在SourceForge偶然发现了这个项目。在我看来,它仍然是活跃的。
- PDF转换为JPEG在SourceForge
- 开发者的网站
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上构建,显然对于商业应用来说,许可问题仍然存在。
(免责声明我是在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