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
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
#include
-------------------------------------------------------------------------------------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(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(FPDF_GetPageWidth(page));
height = static_cast(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(
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上使用,后面再介绍