用Ghostscript API将PDF格式转换为图像格式(C#)
原文:用Ghostscript API将PDF格式转换为图像格式(C#)
由于项目需要在.net下将pdf转换为普通图像格式,在网上搜了好久终于找到一个解决方案,于是采用拿来主义直接用。来源见代码中注释,感谢原作者。
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Collections;
/**
Convert PDF to Image Format(JPEG) using Ghostscript API
convert a pdf to jpeg using ghostscript command line:
gswin32c -q -dQUIET -dPARANOIDSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dFirstPage=1 -dAlignToPixels=0 -dGridFitTT=0 -sDEVICE=jpeg -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -r100x100 -sOutputFile=output.jpg test.pdf
see also:http://www.mattephraim.com/blog/2009/01/06/a-simple-c-wrapper-for-ghostscript/
and: http://www.codeproject.com/KB/cs/GhostScriptUseWithCSharp.aspx
Note:copy gsdll32.dll to system32 directory before using this ghostscript wrapper.
*
*/
namespace ConvertPDF
{
/// <summary>
///
/// Class to convert a pdf to an image using GhostScript DLL
/// Credit for this code go to:Rangel Avulso
/// i only fix a little bug and refactor a little
/// http://www.hrangel.com.br/index.php/2006/12/04/converter-pdf-para-imagem-jpeg-em-c/
/// </summary>
/// <seealso cref="http://www.hrangel.com.br/index.php/2006/12/04/converter-pdf-para-imagem-jpeg-em-c/"/>
class PDFConvert
{
#region GhostScript Import
/// <summary>Create a new instance of Ghostscript. This instance is passed to most other gsapi functions. The caller_handle will be provided to callback functions.
/// At this stage, Ghostscript supports only one instance. </summary>
/// <param name="pinstance"></param>
/// <param name="caller_handle"></param>
/// <returns></returns>
[DllImport("gsdll32.dll", EntryPoint="gsapi_new_instance")]
private static extern int gsapi_new_instance (out IntPtr pinstance, IntPtr caller_handle);
/// <summary>This is the important function that will perform the conversion</summary>
/// <param name="instance"></param>
/// <param name="argc"></param>
/// <param name="argv"></param>
/// <returns></returns>
[DllImport("gsdll32.dll", EntryPoint="gsapi_init_with_args")]
private static extern int gsapi_init_with_args (IntPtr instance, int argc, IntPtr argv);
/// <summary>
/// Exit the interpreter. This must be called on shutdown if gsapi_init_with_args() has been called, and just before gsapi_delete_instance().
/// </summary>
/// <param name="instance"></param>
/// <returns></returns>
[DllImport("gsdll32.dll", EntryPoint="gsapi_exit")]
private static extern int gsapi_exit (IntPtr instance);
/// <summary>
/// Destroy an instance of Ghostscript. Before you call this, Ghostscript must have finished. If Ghostscript has been initialised, you must call gsapi_exit before gsapi_delete_instance.
/// </summary>
/// <param name="instance"></param>
[DllImport("gsdll32.dll", EntryPoint="gsapi_delete_instance")]
private static extern void gsapi_delete_instance (IntPtr instance);
#endregion
#region Variables
private string _sDeviceFormat;
private int _iWidth;
private int _iHeight;
private int _iResolutionX;
private int _iResolutionY;
private int _iJPEGQuality;
private Boolean _bFitPage;
private IntPtr _objHandle;
#endregion
#region Proprieties
public string OutputFormat
{
get { return _sDeviceFormat; }
set { _sDeviceFormat = value; }
}
public int Width
{
get { return _iWidth; }
set { _iWidth = value; }
}
public int Height
{
get { return _iHeight; }
set { _iHeight = value; }
}
public int ResolutionX
{
get { return _iResolutionX; }
set { _iResolutionX = value; }
}
public int ResolutionY
{
get { return _iResolutionY; }
set { _iResolutionY = value; }
}
public Boolean FitPage
{
get { return _bFitPage; }
set { _bFitPage = value; }
}
/// <summary>Quality of compression of JPG</summary>
public int JPEGQuality
{
get { return _iJPEGQuality; }
set { _iJPEGQuality = value; }
}
#endregion
#region Init
public PDFConvert(IntPtr objHandle)
{
_objHandle = objHandle;
}
public PDFConvert()
{
_objHandle = IntPtr.Zero;
}
#endregion
private byte[] StringToAnsiZ(string str)
{
//' Convert a Unicode string to a null terminated Ansi string for Ghostscript.
//' The result is stored in a byte array. Later you will need to convert
//' this byte array to a pointer with GCHandle.Alloc(XXXX, GCHandleType.Pinned)
//' and GSHandle.AddrOfPinnedObject()
int intElementCount;
int intCounter;
byte[] aAnsi;
byte bChar;
intElementCount = str.Length;
aAnsi = new byte[intElementCount+1];
for(intCounter = 0; intCounter < intElementCount;intCounter++)
{
bChar = (byte)str[intCounter];
aAnsi[intCounter] = bChar;
}
aAnsi[intElementCount] = 0;
return aAnsi;
}
/// <summary>Convert the file!</summary>
public void Convert(string inputFile,string outputFile,
int firstPage, int lastPage, string deviceFormat, int width, int height)
{
//Avoid to work when the file doesn't exist
if (!System.IO.File.Exists(inputFile))
{
System.Windows.Forms.MessageBox.Show(string.Format("The file :'{0}' doesn't exist",inputFile));
return;
}
int intReturn;
IntPtr intGSInstanceHandle;
object[] aAnsiArgs;
IntPtr[] aPtrArgs;
GCHandle[] aGCHandle;
int intCounter;
int intElementCount;
IntPtr callerHandle;
GCHandle gchandleArgs;
IntPtr intptrArgs;
string[] sArgs = GetGeneratedArgs(inputFile,outputFile,
firstPage, lastPage, deviceFormat, width, height);
// Convert the Unicode strings to null terminated ANSI byte arrays
// then get pointers to the byte arrays.
intElementCount = sArgs.Length;
aAnsiArgs = new object[intElementCount];
aPtrArgs = new IntPtr[intElementCount];
aGCHandle = new GCHandle[intElementCount];
// Create a handle for each of the arguments after
// they've been converted to an ANSI null terminated
// string. Then store the pointers for each of the handles
for(intCounter = 0; intCounter< intElementCount; intCounter++)
{
aAnsiArgs[intCounter] = StringToAnsiZ(sArgs[intCounter]);
aGCHandle[intCounter] = GCHandle.Alloc(aAnsiArgs[intCounter], GCHandleType.Pinned);
aPtrArgs[intCounter] = aGCHandle[intCounter].AddrOfPinnedObject();
}
// Get a new handle for the array of argument pointers
gchandleArgs = GCHandle.Alloc(aPtrArgs, GCHandleType.Pinned);
intptrArgs = gchandleArgs.AddrOfPinnedObject();
intReturn = gsapi_new_instance(out intGSInstanceHandle, _objHandle);
callerHandle = IntPtr.Zero;
try
{
intReturn = gsapi_init_with_args(intGSInstanceHandle, intElementCount, intptrArgs);
}
catch (Exception ex)
{
//System.Windows.Forms.MessageBox.Show(ex.Message);
}
finally
{
for (intCounter = 0; intCounter < intReturn; intCounter++)
{
aGCHandle[intCounter].Free();
}
gchandleArgs.Free();
gsapi_exit(intGSInstanceHandle);
gsapi_delete_instance(intGSInstanceHandle);
}
}
private string[] GetGeneratedArgs(string inputFile, string outputFile,
int firstPage, int lastPage, string deviceFormat, int width, int height)
{
this._sDeviceFormat = deviceFormat;
this._iResolutionX = width;
this._iResolutionY = height;
// Count how many extra args are need - HRangel - 11/29/2006, 3:13:43 PM
ArrayList lstExtraArgs = new ArrayList();
if ( _sDeviceFormat=="jpg" && _iJPEGQuality > 0 && _iJPEGQuality < 101)
lstExtraArgs.Add("-dJPEGQ=" + _iJPEGQuality);
if (_iWidth > 0 && _iHeight > 0)
lstExtraArgs.Add("-g" + _iWidth + "x" + _iHeight);
if (_bFitPage)
lstExtraArgs.Add("-dPDFFitPage");
if (_iResolutionX > 0)
{
if (_iResolutionY > 0)
lstExtraArgs.Add("-r" + _iResolutionX + "x" + _iResolutionY);
else
lstExtraArgs.Add("-r" + _iResolutionX);
}
// Load Fixed Args - HRangel - 11/29/2006, 3:34:02 PM
int iFixedCount = 17;
int iExtraArgsCount = lstExtraArgs.Count;
string[] args = new string[iFixedCount + lstExtraArgs.Count];
/*
// Keep gs from writing information to standard output
"-q",
"-dQUIET",
"-dPARANOIDSAFER", // Run this command in safe mode
"-dBATCH", // Keep gs from going into interactive mode
"-dNOPAUSE", // Do not prompt and pause for each page
"-dNOPROMPT", // Disable prompts for user interaction
"-dMaxBitmap=500000000", // Set high for better performance
// Set the starting and ending pages
String.Format("-dFirstPage={0}", firstPage),
String.Format("-dLastPage={0}", lastPage),
// Configure the output anti-aliasing, resolution, etc
"-dAlignToPixels=0",
"-dGridFitTT=0",
"-sDEVICE=jpeg",
"-dTextAlphaBits=4",
"-dGraphicsAlphaBits=4",
*/
args[0]="pdf2img";//this parameter have little real use
args[1]="-dNOPAUSE";//I don't want interruptions
args[2]="-dBATCH";//stop after
//args[3]="-dSAFER";
args[3] = "-dPARANOIDSAFER";
args[4]="-sDEVICE="+_sDeviceFormat;//what kind of export format i should provide
args[5] = "-q";
args[6] = "-dQUIET";
args[7] = "-dNOPROMPT";
args[8] = "-dMaxBitmap=500000000";
args[9] = String.Format("-dFirstPage={0}", firstPage);
args[10] = String.Format("-dLastPage={0}", lastPage);
args[11] = "-dAlignToPixels=0";
args[12] = "-dGridFitTT=0";
args[13] = "-dTextAlphaBits=4";
args[14] = "-dGraphicsAlphaBits=4";
//For a complete list watch here:
//http://pages.cs.wisc.edu/~ghost/doc/cvs/Devices.htm
//Fill the remaining parameters
for (int i=0; i < iExtraArgsCount; i++)
{
args[15+i] = (string) lstExtraArgs[i];
}
//Fill outputfile and inputfile
args[15 + iExtraArgsCount] = string.Format("-sOutputFile={0}",outputFile);
args[16 + iExtraArgsCount] = string.Format("{0}",inputFile);
return args;
}
public void pdf2jpgTest()
{
this.Convert(@"C://tmp//pdfimg//test1.pdf",@"C://tmp//pdfimg//out.jpg",1,1,"jpeg",100,100);
//this.Convert(@"C://tmp//pdfimg//test.pdf", @"C://tmp//pdfimg//out2.jpg", 291, 291, "jpeg", 800, 800);
}
}
}
测试WinForm:
可以采用下面的方式测试调用上面的功能,如:
PDFConvert convertor = new PDFConvert();
convertor.pdf2jpgTest();
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ConvertPDF;
namespace PDF2Img
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
PDFConvert convertor = new PDFConvert();
convertor.pdf2jpgTest();
Image img = Image.FromFile(@"C://tmp//pdfimg//out.jpg");
myBitmap = new Bitmap(img);
Graphics G = this.CreateGraphics();
GraphicsUnit GU = G.PageUnit;
BMPContainer = myBitmap.GetBounds(ref GU); //X,Y = 0
// Graphics g = this.CreateGraphics();
//g.DrawImage(myBitmap, 1, 1);
this.Invalidate();
}
private Bitmap myBitmap;
private RectangleF BMPContainer;
protected override void OnPaint(PaintEventArgs e)
{
Graphics G = e.Graphics;
if (myBitmap != null)
{
G.DrawImage(myBitmap, BMPContainer);
}
base.OnPaint(e);
}
}
}
用Ghostscript API将PDF格式转换为图像格式(C#)的更多相关文章
- C# 将PDF文件转换为word格式
Pdf(Portable Document Format)意为“便携式文档格式”,是现在最流行的文件格式之一,它有很多优点如:尺寸较小.阅读方便.操作系统平台通用等,非常适合在网络上传播和使用.如今在 ...
- java 调用OpenOffice将word格式文件转换为pdf格式
一:环境搭建 OpenOffice 下载地址http://www.openoffice.org/ JodConverter 下载地址http://sourceforge.net/projects/jo ...
- CEBX格式的文档如何转换为PDF格式文档、DOCX文档?
方正阿帕比CEBX格式的文档如何转换为PDF格式文档.DOCX文档? 简介: PDF.Doc.Docx格式的文档使用的非常普遍,金山WPS可以直接打开PDF和Doc.Docx文档,使用也很方便. CE ...
- 电子书转换为PDF格式
目录 一.mobi 转换 pdf 步骤 二.查看转换后的结果目录 三.将PDF还原文件名且移出至新目录 背景:当我们从网上下载一些电子小说或书籍的时候,一般文件的格式可能是.epub..mobi等.这 ...
- C#实现office文档转换为PDF格式
1.安装组件OfficeSaveAsPDFandXPS 需要安装office 2007 还有一个office2007的插件OfficeSaveAsPDFandXPS 下载地址 OfficeSave ...
- java使用jacob将office文档转换为PDF格式
jacob 包下载地址: http://sourceforge.net/projects/jacob-project/ 下载后,将jacob 与 jacob-1.19-x64.dll放到安装jdk目录 ...
- 文档转换为pdf格式帮助类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Word = M ...
- ImageMagick convert多张照片JPG转成pdf格式,pdfunite合并PDF文件
在认识ImageMagick之前,我***的图像浏览软件是KuickShow,截图软件是KSnapShot,这两款软件都是KDE附带的软件,用起来也是蛮方便的.在一次偶然的机会中,我遇到了Imag ...
- 初探JavaScript PDF blob转换为Word docx方法
PDF转WORD为什么是历史难题 PDF 转Word 是一个非常非常普遍的需求,可谓人人忌危,为什么如此普遍的需求,却如此难行呢,还得看为什么会有这样的一个需求: PDF文档遵循iOS32000的规范 ...
随机推荐
- WPF-21:WPF实现仿安卓的图案密码键盘(初级)
希望大家有这方面好的代码给提供下,谢谢了! 想用C#做一个和手机上一样的图形密码键盘,貌似这方面资料比较少,虽然winphone手机上也有但是网上也没有这方面的代码.只好用常规的思维去实现一下,当然是 ...
- Codeforces Round#201(div1) D. Lucky Common Subsequence
题意:给定两个串,求出两个串的最长公共子序列,要求该公共子序列不包含virus串. 用dp+kmp实现 dp[i][j][k]表示以i结尾的字符串和以j结尾的字符串的公共子序列的长度(其中k表示该公共 ...
- AMD宣布裁员7% 约710员工将失去工作
10 月 17 日.美国芯片生产商 AMD 周四宣布将裁员7%.并公布了不及预期的第四季度业绩展望.这将是 AMD 自 2011 年以来的第三轮大裁员. 就在一周之前,AMD 宣布罗瑞德(Rory R ...
- 【PHP】PHP5.4.0版本号ChangeLog具体解释(上)
前言 随着大量的框架使用composer和namespace,渐渐的线上环境也从之前的5.3变成了5.4或者5.5甚至5.6,随着7月份PHP7的公布,会有很多其它的公司採用新版本号. 之前好久就想写 ...
- Java乔晓松-android的四大组件之一Service(服务的绑定)
android的四大组件之一Service(服务的绑定) 怎么绑定服务,又怎么解除服务,代码如下: MainActivity.java源码: package com.example.lesson14_ ...
- 排列组合相关算法 python
获取指定长度得全部序列 通过事件来表述这个序列,即n重伯努利实验(二项分布)的全部可能结果.比如时间a表示为: a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 假设每次实验为从 ...
- repo总结
repo刚google使用Python脚本写通话git脚本.主要用于下载.管理Android工程仓库. 1. 下载 repo 的地址: http://android.git.kernel.org/re ...
- Windows Server 2012 R2在桌面上显示计算机/网络图标
原文 Windows Server 2012 R2在桌面上显示计算机/网络图标 从Windows2012开始,微软取消了服务器桌面个性化选项,如何重新调出配置界面,可以使用微软命令调出.具体方法如下: ...
- 在基于阿里云serverCentOS6.5下安装Subversion 1.6.5服务
近期阿里云搞了个1元免费提供云server的活动,偶心痒痒就申请了一个. 正好能够作为团队的SVNserver了,以下就来部署SVN服务吧. 一.安装基础环境 apr-1.5.0.tar.gz apr ...
- 在C#环境中动态调用IronPython脚本(二)
一.Python数据类型与C#数据类型的对应 Python中数据类型中的简单类型,例如int,float,string可以对应到C#环境中的int32,double,string,这些对应比较直观,P ...