背景
俺在之前的博客中提到了 把PDF的每一页另存为图片的方法。当时是使用的Devexpress。因为Devexpress确实很方便,因为 Devexpress 自带了PdfViewer的控件。直接使用**PdfViewer的CreateBitmap(i_page_no, bmp_w)**就可以。最近遇到了一个很特别的pdf,这个pdf使用Devexpress 会只显示位置,pdf里的背景图无法显示,转出的图片中也丢失了背景图。所以俺就使用了另外的方法。
另一种方法
通过Nuget 安装 Ghostscript.NET

然后使用 GhostscriptRasterizer 获得每一页的图片
int pageCount = 0;
using (var rasterizer = new GhostscriptRasterizer ())
{
var gsVersion = new GhostscriptVersionInfo(ghostscriptDllPath);
rasterizer.Open(pdfPath, gsVersion, true);
pageCount = rasterizer.PageCount;
for (int pageNumber = 1; pageNumber <= pageCount; pageNumber++)
{
SkiaSharp.SKBitmap image = rasterizer.GetPage(dpi, pageNumber);
注意
需要的dll

调用时可以放在执行目录的gs子目录下
private void button_proc_Click(object sender, EventArgs e)
{
string fn = textBox1.Text.Trim();
if (File.Exists(fn))
{
string path = Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
string DllPath = Path.Combine(path, "gs", "gsdll64.dll");
string dir = fn + ".pages";
button_proc.Enabled = false;
progressBar1.Visible = true;
Application.DoEvents();
GsPdf2Img gs = new GsPdf2Img();
gs.convertProgressEvent += proc_convertProgressEvent;
gs.imgFormat = "jpg";
gs.ghostscriptDllPath = DllPath;
gs.ConvertPdfToImages(fn, dir, 96);
progressBar1.Visible = false;
button_proc.Enabled = true;
MessageBox.Show("save to "+ dir);
}
}
代码
cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ghostscript.NET;
using Ghostscript.NET.Rasterizer;
namespace PDF2IMG
{
public class GsPdf2Img
{
public string ghostscriptDllPath = @"C:\Program Files\gs\gs10.06.0\bin\gsdll64.dll";
public string imgFormat = "jpg";
public event EventHandler<ConvertPdfToImagesEventArgs> convertProgressEvent;
public void ConvertPdfToImages(string pdfPath, string outputDir, int dpi = 300 )
{
if (!File.Exists(pdfPath))
return;
if (!Directory.Exists(outputDir))
Directory.CreateDirectory(outputDir);
if (!File.Exists(ghostscriptDllPath))
throw new FileNotFoundException("Ghostscript DLL not exists", ghostscriptDllPath);
int pageCount = 0;
using (var rasterizer = new GhostscriptRasterizer())
{
var gsVersion = new GhostscriptVersionInfo(ghostscriptDllPath);
rasterizer.Open(pdfPath, gsVersion, true);
pageCount = rasterizer.PageCount;
for (int pageNumber = 1; pageNumber <= pageCount; pageNumber++)
{
SkiaSharp.SKBitmap image = rasterizer.GetPage(dpi, pageNumber);
if ((string.Compare(imgFormat, "jpg", true) == 0) || (string.Compare(imgFormat, "jpg", true) == 0))
{
string outputPath = Path.Combine(outputDir, pageNumber.ToString()+ ".jpg");
using (var stream = File.OpenWrite(outputPath))
{
image.Encode(SkiaSharp.SKEncodedImageFormat.Jpeg, 100).SaveTo(stream);
}
}
else if ((string.Compare(imgFormat, "png", true) == 0) )
{
string outputPath = Path.Combine(outputDir, pageNumber.ToString() + ".png");
using (var stream = File.OpenWrite(outputPath))
{
image.Encode(SkiaSharp.SKEncodedImageFormat.Png, 100).SaveTo(stream);
}
}
else if ((string.Compare(imgFormat, "bmp", true) == 0))
{
string outputPath = Path.Combine(outputDir, pageNumber.ToString() + ".bmp");
using (var stream = File.OpenWrite(outputPath))
{
image.Encode(SkiaSharp.SKEncodedImageFormat.Bmp, 100).SaveTo(stream);
}
}
image.Dispose();
convertProgressEvent?.Invoke(this, new ConvertPdfToImagesEventArgs(pageNumber, pageCount));
}
rasterizer.Close();
}
}
}
public class ConvertPdfToImagesEventArgs : EventArgs
{
public int Page { get; }
public int TotalCount { get; }
public ConvertPdfToImagesEventArgs(int page, int totalCount)
{
Page = page;
TotalCount = totalCount;
}
}
}