如果你已经按照前面的步骤成功生成了库,那么恭喜你。如果没有也不要气馁 ,我后面会放送编译好的库。
我们可以看一下pdfium的pdfium\build\Debug\lib目录和pdfium\build\Debug\,可以看到其实就一个dll文件和一堆lib。如果使用呢
可以参考pdfium\samples目录下的例子程序。下面我对其进行封装:
首先建立一个win32 dll工程PDFIumReader并引入pdfium头文件和lib目录
并在dllmain函数进行初始化
B#include "stdafx.h" #include "fpdf_ext.h" #include "vld.h" #include "v8.h" #include <iostream> #include <string> void Unsupported_Handler(UNSUPPORT_INFO*, int type) { std::string feature = "Unknown"; switch (type) { case FPDF_UNSP_DOC_XFAFORM: feature = "XFA"; break; case FPDF_UNSP_DOC_PORTABLECOLLECTION: feature = "Portfolios_Packages"; break; case FPDF_UNSP_DOC_ATTACHMENT: case FPDF_UNSP_ANNOT_ATTACHMENT: feature = "Attachment"; break; case FPDF_UNSP_DOC_SECURITY: feature = "Rights_Management"; break; case FPDF_UNSP_DOC_SHAREDREVIEW: feature = "Shared_Review"; break; case FPDF_UNSP_DOC_SHAREDFORM_ACROBAT: case FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM: case FPDF_UNSP_DOC_SHAREDFORM_EMAIL: feature = "Shared_Form"; break; case FPDF_UNSP_ANNOT_3DANNOT: feature = "3D"; break; case FPDF_UNSP_ANNOT_MOVIE: feature = "Movie"; break; case FPDF_UNSP_ANNOT_SOUND: feature = "Sound"; break; case FPDF_UNSP_ANNOT_SCREEN_MEDIA: case FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA: feature = "Screen"; break; case FPDF_UNSP_ANNOT_SIG: feature = "Digital_Signature"; break; } printf("Unsupported feature: %s.\n", feature.c_str()); } BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { v8::V8::InitializeICU(); FPDF_InitLibrary(NULL); UNSUPPORT_INFO unsuppored_info; memset(&unsuppored_info, '\0', sizeof(unsuppored_info)); unsuppored_info.version = 1; unsuppored_info.FSDK_UnSupport_Handler = Unsupported_Handler; FSDK_SetUnSpObjProcessHandler(&unsuppored_info); } break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: FPDF_DestroyLibrary(); break; } return TRUE; }
然后新建一个类PDFIumReaderMgr用于管理多个pdf
头文件:
PDFIumReaderMgr
#pragma once #include <iostream> #include <map> class PDFIumReader; typedef std::map<std::string, PDFIumReader*> PDFReaders; class PDFIumReaderMgr { public: static PDFIumReaderMgr *Instance(); bool LoadPDF(const char *name); void Closepdf(const char *name); char *LoadPage(const char* filename, int page, float& width, float& height, bool OutBmp); int GetPageCount(const char* filename); char* GetNextPage(const char* filename, int &page, float& width, float& height, bool OutBmp); void SetCurrentPage(const char* filename, int page); private: PDFIumReaderMgr(){} ~PDFIumReaderMgr(){} public: PDFReaders m_pdfReaders;};
------------------------------------------------------------------------------------PDFIumReaderMgr.cpp-----------------------------------------------------------------------------------------------
#include "stdafx.h" #include "PDFReaderMgr.h" #include "PDFIumReader.h" #include <iostream> using namespace std; PDFIumReaderMgr * PDFIumReaderMgr::Instance() { static PDFIumReaderMgr mgr; return &mgr; } bool PDFIumReaderMgr::LoadPDF(const char *name) { if (m_pdfReaders.find(name) != m_pdfReaders.end()) { std::cout << "this file has loaded" << endl; return true; } PDFIumReader *reader = new PDFIumReader(); m_pdfReaders[name] = reader; return reader->Reader(name); } void PDFIumReaderMgr::Closepdf(const char *name) { if (m_pdfReaders.find(name) == m_pdfReaders.end()) return; m_pdfReaders.find(name)->second->Close(); m_pdfReaders.erase(name); } char * PDFIumReaderMgr::LoadPage(const char* filename, int page, float& width, float& height, bool OutBmp) { if (m_pdfReaders.find(filename) == m_pdfReaders.end()) return 0; return m_pdfReaders.find(filename)->second->GetPdfPage(page, width, height, OutBmp); } int PDFIumReaderMgr::GetPageCount(const char* filename) { if (m_pdfReaders.find(filename) == m_pdfReaders.end()) return 0; return m_pdfReaders.find(filename)->second->GetPageCount(); } char* PDFIumReaderMgr::GetNextPage(const char* filename, int &page, float& width, float& height, bool OutBmp) { if (m_pdfReaders.find(filename) == m_pdfReaders.end()) return 0; return m_pdfReaders.find(filename)->second->GetNextPage(page, width, height, OutBmp); } void PDFIumReaderMgr::SetCurrentPage(const char* filename, int page) { if (m_pdfReaders.find(filename) == m_pdfReaders.end()) return ; m_pdfReaders.find(filename)->second->SetCurrentPage(page); } 最后创建一个真正读取pdf的类PDFIumReader
-------------------------------------------------------------------------PDFIumReader.h-----------------------------------------------------------------------------------------
#pragma once #include "fpdf_dataavail.h" #include "fpdfview.h" #include "fpdfformfill.h" #include "fpdf_dataavail.h" #include "fpdfedit.h" #include "fpdftext.h" #include "fpdfview.h" #include <memory> #include <map> #include <sstream> #include <string> #include <utility> #include <vector> #include <iostream> #include <string> enum ResultType { PDF_DATA_ERROR = 0, PDF_DATA_NO_ERROR = 1, PDF_DATA_NO_DATA = 2 }; enum Output_Type { OUTPUT_STR, OUTPUT_BMP }; class PDFIumLoader { public: PDFIumLoader(){} PDFIumLoader(const char* pBuf, size_t len); const char* m_pBuf; size_t m_Len; }; class PDFIumReader { private: static void WritePpm(const char* pdf_name, int num, const char* buffer, int stride, int width, int height); static void AddSegment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size); static bool IsDataAvail(FX_FILEAVAIL* pThis, size_t offset, size_t size); static int GetBlock(void* param, unsigned long pos, unsigned char* pBuf, unsigned long size); static int FormAlert(IPDF_JSPLATFORM*, FPDF_WIDESTRING, FPDF_WIDESTRING, int, int); public: PDFIumReader(){} ~PDFIumReader(); bool Reader(const char *name); void Close(); char* GetPdfPage(int pageIndex, float& width, float& height, bool OutBmp = false); int GetPageCount(){ return m_nPageCount; } char* GetNextPage(int &page, float& width, float& height, bool OutBmp); void SetCurrentPage(int page); private: void RenderPdf(const char* pBuf, size_t len); private: FPDF_DOCUMENT m_pPdfDoc = nullptr; FPDF_FORMFILLINFO m_formCallbacks; IPDF_JSPLATFORM m_platformcallbacks; FPDF_FORMHANDLE m_formHandle; FX_DOWNLOADHINTS m_hints; FX_FILEAVAIL m_fileAvail; FPDF_FILEACCESS m_fileAccess; PDFIumLoader m_PDFIumLoader; FPDF_AVAIL m_PdfAvail; char *m_pdfBuf; bool m_bIsLinearized = false; std::string m_strFileName; int m_nPageCount = 0; int m_nCurrentPage = 0; };
-------------------------------------------------------------------------------------PDFIumReader.cpp______________________________________________
#include "PDFIumReader.h" using namespace std; void PDFIumReader::RenderPdf(const char* pBuf, size_t len) { memset(&m_platformcallbacks, '\0', sizeof(m_platformcallbacks)); m_platformcallbacks.version = 1; m_platformcallbacks.app_alert = FormAlert; memset(&m_formCallbacks, '\0', sizeof(m_formCallbacks)); m_formCallbacks.version = 1; m_formCallbacks.m_pJsPlatform = &m_platformcallbacks; m_PDFIumLoader.m_pBuf = pBuf; m_PDFIumLoader.m_Len = len; memset(&m_fileAccess, '\0', sizeof(m_fileAccess)); m_fileAccess.m_FileLen = static_cast<unsigned long>(len); m_fileAccess.m_GetBlock = GetBlock; m_fileAccess.m_Param = &m_PDFIumLoader; memset(&m_fileAvail, '\0', sizeof(m_fileAvail)); m_fileAvail.version = 1; m_fileAvail.IsDataAvail = IsDataAvail; memset(&m_hints, '\0', sizeof(m_hints)); m_hints.version = 1; m_hints.AddSegment = AddSegment; m_PdfAvail = FPDFAvail_Create(&m_fileAvail, &m_fileAccess); (void)FPDFAvail_IsDocAvail(m_PdfAvail, &m_hints); if (!FPDFAvail_IsLinearized(m_PdfAvail)) { printf("Non-linearized path...\n"); m_pPdfDoc = FPDF_LoadCustomDocument(&m_fileAccess, NULL); } else { printf("Linearized path...\n"); m_pPdfDoc = FPDFAvail_GetDocument(m_PdfAvail, NULL); } (void)FPDF_GetDocPermissions(m_pPdfDoc); (void)FPDFAvail_IsFormAvail(m_PdfAvail, &m_hints); m_formHandle = FPDFDOC_InitFormFillEnviroument(m_pPdfDoc, &m_formCallbacks); FPDF_SetFormFieldHighlightColor(m_formHandle, 0, 0xFFE4DD); FPDF_SetFormFieldHighlightAlpha(m_formHandle, 100); int first_page = FPDFAvail_GetFirstPageNum(m_pPdfDoc); FPDFAvail_IsPageAvail(m_PdfAvail, first_page, &m_hints); m_nPageCount = FPDF_GetPageCount(m_pPdfDoc); for (int i = 0; i < m_nPageCount; ++i) { FPDFAvail_IsPageAvail(m_PdfAvail, i, &m_hints); } FORM_DoDocumentJSAction(m_formHandle); FORM_DoDocumentOpenAction(m_formHandle); } void PDFIumReader::WritePpm(const char* pdf_name, int num, const char* buffer, int stride, int width, int height) { if (stride < 0 || width < 0 || height < 0) return; if (height > 0 && width > INT_MAX / height) return; int out_len = width * height; if (out_len > INT_MAX / 3) return; out_len *= 3; char filename[256]; _snprintf(filename, sizeof(filename), "%s.%d.ppm", pdf_name, num); FILE* fp = fopen(filename, "w"); if (!fp) return; fprintf(fp, "P6\n# PDF test render\n%d %d\n255\n", width, height); // Source data is B, G, R, unused. // Dest data is R, G, B. char* result = new char[out_len]; if (result) { for (int h = 0; h < height; ++h) { const char* src_line = buffer + (stride * h); char* dest_line = result + (width * h * 3); for (int w = 0; w < width; ++w) { // R dest_line[w * 3] = src_line[(w * 4) + 2]; // G dest_line[(w * 3) + 1] = src_line[(w * 4) + 1]; // B dest_line[(w * 3) + 2] = src_line[w * 4]; } } fwrite(result, out_len, 1, fp); delete[] result; } fclose(fp); } void PDFIumReader::AddSegment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) { } bool PDFIumReader::IsDataAvail(FX_FILEAVAIL* pThis, size_t offset, size_t size) { return true; } int PDFIumReader::GetBlock(void* param, unsigned long pos, unsigned char* pBuf, unsigned long size) { PDFIumLoader* pLoader = (PDFIumLoader*)param; if (pos + size < pos || pos + size > pLoader->m_Len) return 0; memcpy(pBuf, pLoader->m_pBuf + pos, size); return 1; } int PDFIumReader::FormAlert(IPDF_JSPLATFORM*, FPDF_WIDESTRING, FPDF_WIDESTRING, int, int) { printf("Form_Alert called.\n"); return 0; } PDFIumReader::~PDFIumReader() { Close(); } bool PDFIumReader::Reader(const char *filename) { if (NULL == filename) return false; m_strFileName = filename; FILE* file = fopen(filename, "rb"); if (!file) { fprintf(stderr, "Failed to open: %s\n", filename); return false; } (void)fseek(file, 0, SEEK_END); size_t len = ftell(file); (void)fseek(file, 0, SEEK_SET); m_pdfBuf = (char*)malloc(len); size_t ret = fread(m_pdfBuf, 1, len, file); (void)fclose(file); RenderPdf(m_pdfBuf, len); return true; } char* PDFIumReader::GetPdfPage(int pageIndex, float& width, float& height, bool OutBmp) { if (pageIndex < 0) return 0; pageIndex = min(pageIndex, m_nPageCount - 1); m_nCurrentPage = pageIndex; FPDF_PAGE page = FPDF_LoadPage(m_pPdfDoc, pageIndex); FPDF_TEXTPAGE text_page = FPDFText_LoadPage(page); FORM_OnAfterLoadPage(page, m_formHandle); FORM_DoPageAAction(page, m_formHandle, FPDFPAGE_AACTION_OPEN); width = static_cast<int>(FPDF_GetPageWidth(page)); height = static_cast<int>(FPDF_GetPageHeight(page)); FPDF_BITMAP bitmap = FPDFBitmap_Create(width, height, 0); FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 255, 255, 255, 255); FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, 0); FPDF_FFLDraw(m_formHandle, bitmap, page, 0, 0, width, height, 0, 0); char* buffer = reinterpret_cast<char*>( FPDFBitmap_GetBuffer(bitmap)); if (OutBmp) { int stride = FPDFBitmap_GetStride(bitmap); WritePpm(m_strFileName.c_str(), pageIndex, buffer, stride, width, height); } FPDFBitmap_Destroy(bitmap); FORM_DoPageAAction(page, m_formHandle, FPDFPAGE_AACTION_CLOSE); FORM_OnBeforeClosePage(page, m_formHandle); FPDFText_ClosePage(text_page); FPDF_ClosePage(page); return buffer; } char* PDFIumReader::GetNextPage(int &page, float& width, float& height, bool OutBmp) { page = ++m_nCurrentPage; page = min(page, m_nPageCount - 1); page = max(0, page); return GetPdfPage(page, width, height, OutBmp); } void PDFIumReader::SetCurrentPage(int page) { m_nCurrentPage = page; m_nCurrentPage = min(m_nCurrentPage, m_nPageCount - 1); m_nCurrentPage = max(0, m_nCurrentPage); } void PDFIumReader::Close() { if (!this->m_pPdfDoc) return; FORM_DoDocumentAAction(this->m_pPdfDoc, FPDFDOC_AACTION_WC); FPDFDOC_ExitFormFillEnviroument(this->m_formHandle); FPDF_CloseDocument(this->m_pPdfDoc); FPDFAvail_Destroy(this->m_PdfAvail); free(m_pdfBuf); this->m_pPdfDoc = NULL; } PDFIumLoader::PDFIumLoader(const char* pBuf, size_t len) : m_pBuf(pBuf), m_Len(len) { }
然后建立导出接口:新建一个PDFIumReaerII.h
加入如下导出接口:
#ifndef _PDF_IUM_READER_H_ #define _PDF_IUM_READER_H_
#ifdef PDF_IUM_READER_API extern "C" _declspec(dllexport) #else #define PDF_IUM_READER_API extern "C" _declspec(dllexport) #endif
//加载 PDF_IUM_READER_API bool PDFIumReader_Loadpdf(const char* filename, int length); //关闭 PDF_IUM_READER_API bool PDFIumReader_Closepdf(const char* filename); //加载某个page PDF_IUM_READER_API char* PDFIumReader_LoadPage(const char* filename, int page, float& width, float& height, int& size, bool OutBmp); //关闭个page PDF_IUM_READER_API void PDFIumReader_ClosePage(const char* filename, int page); //获取总页数 PDF_IUM_READER_API int PDFIumReader_GetPageCount(const char* filename); //获取下一页该渲染的页 PDF_IUM_READER_API int PDFIumReader_GetNextPage(const char* filename); #endif
最后定义导出函数如下
--------------------------------------------------------------------------PDFIumReaderII.h-----------------------------------------------------------------------------------------------
#ifndef _PDF_IUM_READER_H_ #define _PDF_IUM_READER_H_ #ifdef PDF_IUM_READER_API extern "C" _declspec(dllexport) #else #define PDF_IUM_READER_API extern "C" _declspec(dllexport) #endif //加载 PDF_IUM_READER_API bool PDFIumReader_Loadpdf(const char* filename); //关闭 PDF_IUM_READER_API void PDFIumReader_Closepdf(const char* filename); //加载某个page PDF_IUM_READER_API char* PDFIumReader_GetPage(const char* filename, int page, float& width, float& height, bool OutBmp = false); //获取总页数 PDF_IUM_READER_API int PDFIumReader_GetPageCount(const char* filename); //获取下一页该渲染的页 PDF_IUM_READER_API char* PDFIumReader_GetNextPage(const char* filename, int &page, float& width, float& height, bool OutBmp =false); //设置当前页 PDF_IUM_READER_API void PDFIumReader_SetCurrentPage(const char* filename, int page); #endif
--------------------------------------------------------------------PDFIumReaderII.cpp----------------------------------------------------------------------------------------
// PdfIumManager.cpp : 定义 DLL 应用程序的导出函数。 // #include "PDFIumReaderII.h" #include "PDFReaderMgr.h" using namespace std; PDF_IUM_READER_API bool PDFIumReader_Loadpdf(const char* filename) { return PDFIumReaderMgr::Instance()->LoadPDF(filename); } PDF_IUM_READER_API void PDFIumReader_Closepdf(const char* filename) { PDFIumReaderMgr::Instance()->Closepdf(filename); } PDF_IUM_READER_API char* PDFIumReader_GetPage(const char* filename, int page, float& width, float& height, bool OutBmp) { return PDFIumReaderMgr::Instance()->LoadPage(filename, page, width, height, OutBmp); } PDF_IUM_READER_API int PDFIumReader_GetPageCount(const char* filename) { return PDFIumReaderMgr::Instance()->GetPageCount(filename); } PDF_IUM_READER_API char * PDFIumReader_GetNextPage(const char* filename, int &page, float& width, float& height, bool OutBmp) { return PDFIumReaderMgr::Instance()->GetNextPage(filename, page, width, height, OutBmp); } PDF_IUM_READER_API void PDFIumReader_SetCurrentPage(const char* filename, int page) { PDFIumReaderMgr::Instance()->SetCurrentPage(filename, page); }
最后引入库 如果编译32为引入32的pdfium库 64的引入64位库
使用:
#include "F:\\Qt-pdf\\PdfIumReader64\\PdfIumManager\\PDFIumReaderII.h" #pragma comment(lib, "F:\\Work\\Win32Project2\\x64\\Debug\\PDFIumReaderII.lib") int _tmain(int argc, _TCHAR* argv[]) { PDFIumReader_Loadpdf("F:\\Work\\Win32Project2\\x64\\Debug\\1.pdf"); int counts = PDFIumReader_GetPageCount("F:\\Work\\Win32Project2\\x64\\Debug\\1.pdf"); for (int i = 0; i < counts; ++i) { float width, height = 0; int length = 0; char *buf = PDFIumReader_GetPage("F:\\Work\\Win32Project2\\x64\\Debug\\1.pdf", i, width, height,true); } PDFIumReader_Closepdf("F:\\Work\\Win32Project2\\x64\\Debug\\1.pdf"); getchar(); return 0; }
这里返回的是char类型的数据,可以直接在vc和Qt上使用,后面再介绍
