各种PDF转换问题(一).在C++中借助Acrobat将PDF转为TIFF

来源:互联网 发布:java runtime class 编辑:程序博客网 时间:2024/05/16 19:14

总是碰到各种PDF相关的转换问题。故记录一二,以作总结。


此处是借助Acrobat来进行转换,首先要安装Acrobat,装完后,系统中会有Acrobat 的COM库,同时,安装目录下有一个Acrobat.tlb和Acrobat.dll文件,这都是我们所需要的。


1.建立C++工程,将tlb添加到工程中(为了方便使用,其实不添加也可以)。在代码中#import "Acrobat.tlb"。


2.定义两个类成员变量:

Acrobat::CAcroAppPtracrapp;Acrobat::CAcroPDDocPtr  acrdoc;

3.在类构造函数中,对COM进行初始化,同时初始化以上两个变量,析构函数反之(这里COM初始化和卸载因实际需要而谨慎处理):

CSigner() : strError(L""), acrapp(NULL), acrdoc(NULL){::CoInitialize(NULL);}~CSigner(){::CoUninitialize();}

4.在类的初始化函数中,创建COM实例:

if(NULL == acrapp){acrapp.CreateInstance(Acrobat::CLSID_AcroApp);acrapp->Hide(&ret);}if(NULL == acrdoc){acrdoc.CreateInstance(Acrobat::CLSID_AcroPDDoc);}

5.关键部分来了。调用Acrobat COM组件的SaveAs方法,做“另存为”操作,即可将PDF转为其它格式(具体格式字符串网上可查):

// TODO: 在此添加实现代码HRESULT hr = S_OK;try{VARIANT_BOOL ret = VARIANT_TRUE;hr = acrdoc->Open(strPdfPath, &ret);if(FAILED(hr))throw (hr);IDispatch FAR* jso = NULL;hr = acrdoc->GetJSObject(&jso);if(FAILED(hr))throw (hr);DISPID dispId;OLECHAR FAR* szMember = L"SaveAs";hr = jso->GetIDsOfNames(IID_NULL, &szMember, 1, LOCALE_SYSTEM_DEFAULT, &dispId);if(FAILED(hr))throw (hr);DISPPARAMS dispParams;memset(&dispParams, 0, sizeof(dispParams));dispParams.cArgs = 2;CComVariant* pVars = new CComVariant[2];pVars[1] = strTifPath;pVars[0] = L"com.adobe.acrobat.tiff";pVars[1].ChangeType(VT_BSTR);pVars[0].ChangeType(VT_BSTR);dispParams.rgvarg = pVars;dispParams.cNamedArgs = 0;EXCEPINFO excepInfo;memset(&excepInfo, 0, sizeof(excepInfo));CComVariant vaResult;UINT nArgErr = (UINT)-1;hr = jso->Invoke(dispId, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispParams, &vaResult, &excepInfo, &nArgErr);delete[] pVars;*state = hr;return hr;}catch(_com_error ce){strError = ce.ErrorMessage();*state = hr;return S_FALSE;}catch(...){*state = hr;return S_OK;}

第5步骤同时也展示了C++中调用JSObject的方法,即使用最原始的COM调用手段,MSDN上也有说明,但很不详细。