将pdf文件转换成图片文件
概要
现在手头的项目有一个需求是要从微信卡包里面拉取发票下来,把它的PDF文档保存下来,并且转换成图片保存在本地,我以前也使用过像Components.PDFRender4NET.dll这些PDF插件,可是这些都测试了一下,或多或少有一些地方不是很满意,转换出来的发票图片有点模糊。最后同事推荐我使用Acrobat,结果真是让我惊喜。作为Adobe官方出品产品,其转换效率要比其他的DLL要快多了,而且应该更可靠一些。所以迫不及待的想和大家分享一下我的使用经验。
使用该插件基本要求:
开发环境:VS2017,.Net Framework4.5.2,Adobe Acrobat9.0
工程中添加COM引用:Adobe Acrobat 9.0 Type Library(必须装了Adobe Acrobat9.0才会有),从安装文件copy出Acrobat.dll就可以。有些机器可直接注册Acrobat.dll,不需要安装Adobe Acrobat9.0,注册步骤,如果是32位系统,把Acrobat.dll拷贝到C:\Windows\System32目录下,是64位系统,那就把Acrobat.dll拷贝到C:\Windows\SysWOW64目录下,然后在运行栏输入regsvr32 Acrobat.dll命令进行注册;如果注册不成功,就安装Adobe Acrobat9.0。
思路:
1、需要用到的COM对象:
1)CAcroPDDoc:Acrobat文档对象。
2)CAcroPDPage:页对象。
3)CAcroRect:用来描述页中一个矩形区域的对象。
4)CAcroPoint:实际上代表的是Size。
2、转换过程:
1)打开文档。
2)取出每一页。
3)获取每一页的大小,生成一个表示该页的矩形区域。
4)将当前页的指定区域编码成图片,并且复制到剪贴板中。
5)将剪贴板中的图片取出,保存为图片文件。
转换函数代码:
1 public static class PdfToImag 2 { 3 private class Info 4 { 5 public CAcroPDPage Page; 6 7 public CAcroRect Rect; 8 9 public double Resolution; 10 11 public Bitmap Bitmap = null; 12 } 13 14 [CompilerGenerated] 15 private static class Wo__0 16 { 17 public static CallSite<Func<CallSite, object, CAcroPDPage>> Wp__0; 18 19 public static CallSite<Func<CallSite, object, CAcroPoint>> Wp__1; 20 } 21 /// <summary> 22 /// 23 /// </summary> 24 /// <param name="filePath">pdf路径含扩展名</param> 25 /// <param name="imagPath">图片存放路径含扩展名</param> 26 /// <param name="resolution"></param> 27 /// <returns></returns> 28 public static bool ConvertPDF2Image(string filePath,string imagPath, double resolution = 6.0) 29 { 30 CAcroPDDoc cAcroPDDoc = null; 31 CAcroPDPage cAcroPDPage = null; 32 CAcroRect cAcroRect = null; 33 CAcroPoint cAcroPoint = null; 34 Image result; 35 try 36 { 37 //生成操作Pdf文件的Com对象 38 cAcroPDDoc = (AcroPDDoc)Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("FF76CB60-2E68-101B-B02E-04021C009402"))); 39 bool flag = !cAcroPDDoc.Open(filePath); 40 if (flag) 41 { 42 throw new FileNotFoundException(); 43 } 44 bool flag2 = resolution <= 0.0; 45 if (flag2) 46 { 47 resolution = 1.0; 48 } 49 if (PdfToImag.Wo__0.Wp__0 == null) 50 { 51 PdfToImag.Wo__0.Wp__0 = CallSite<Func<CallSite, object, CAcroPDPage>>.Create(Binder.Convert(CSharpBinderFlags.ConvertExplicit, typeof(CAcroPDPage), typeof(PdfToImag))); 52 } 53 cAcroPDPage = PdfToImag.Wo__0.Wp__0.Target(PdfToImag.Wo__0.Wp__0, cAcroPDDoc.AcquirePage(0)); 54 if (PdfToImag.Wo__0.Wp__1 == null) 55 { 56 PdfToImag.Wo__0.Wp__1 = CallSite<Func<CallSite, object, CAcroPoint>>.Create(Binder.Convert(CSharpBinderFlags.ConvertExplicit, typeof(CAcroPoint), typeof(PdfToImag))); 57 } 58 cAcroPoint = PdfToImag.Wo__0.Wp__1.Target(PdfToImag.Wo__0.Wp__1, cAcroPDPage.GetSize()); 59 cAcroRect = (AcroRect)Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("6D12C400-4E34-101B-9CA8-9240CE2738AE"))); 60 int num = (int)((double)cAcroPoint.x * resolution); 61 int num2 = (int)((double)cAcroPoint.y * resolution); 62 cAcroRect.Left = 0; 63 cAcroRect.right = (short)num; 64 cAcroRect.Top = 0; 65 cAcroRect.bottom = (short)num2; 66 result = PdfToImag.GetclipboardData(cAcroPDPage, cAcroRect, resolution); 67 result.Save(imagPath, System.Drawing.Imaging.ImageFormat.Jpeg); 68 } 69 catch (Exception ex) 70 { 71 return false; 72 } 73 finally 74 { 75 bool flag3 = cAcroPDDoc != null; 76 if (flag3) 77 { 78 if (cAcroPDDoc != null) 79 { 80 cAcroPDDoc.Close(); 81 } 82 } 83 bool flag4 = cAcroPDPage != null; 84 if (flag4) 85 { 86 Marshal.ReleaseComObject(cAcroPDPage); 87 } 88 bool flag5 = cAcroRect != null; 89 if (flag5) 90 { 91 Marshal.ReleaseComObject(cAcroRect); 92 } 93 bool flag6 = cAcroPDDoc != null; 94 if (flag6) 95 { 96 Marshal.ReleaseComObject(cAcroPDDoc); 97 } 98 bool flag7 = cAcroPoint != null; 99 if (flag7) 100 { 101 Marshal.ReleaseComObject(cAcroPoint); 102 } 103 } 104 return true; 105 } 106 107 private static Image GetclipboardData(CAcroPDPage page, CAcroRect pdfRect, double resolution) 108 { 109 PdfToImag.Info info = new PdfToImag.Info 110 { 111 Page = page, 112 Rect = pdfRect, 113 Resolution = resolution 114 }; 115 Thread thread = new Thread(new ParameterizedThreadStart(PdfToImag.CopyToClipboard)); 116 thread.TrySetApartmentState(ApartmentState.STA); 117 thread.Start(info); 118 thread.Join(); 119 return info.Bitmap; 120 } 121 122 [STAThread] 123 private static void CopyToClipboard(object arge) 124 { 125 PdfToImag.Info info = arge as PdfToImag.Info; 126 CAcroPDPage page = info.Page; 127 CAcroRect rect = info.Rect; 128 double resolution = info.Resolution; 129 page.CopyToClipboard(rect, 0, 0, (short)(100.0 * resolution)); 130 IDataObject dataObject = Clipboard.GetDataObject(); 131 bool dataPresent = dataObject.GetDataPresent(DataFormats.Bitmap); 132 if (dataPresent) 133 { 134 Bitmap bitmap = (Bitmap)dataObject.GetData(DataFormats.Bitmap); 135 info.Bitmap = bitmap; 136 } 137 } 138 }