环境:Win10 x64,VS2017, mupdf-1.17.0-source.tar.xz
背景:
项目临时需要将PDF转成PNG, 需要保证画面清晰度和速度, 网上有多种方式 ImageMagick,Mupdf..
ImageMagick 按照网上的教程,搞了半天没搞明白,然后换成了Mupdf,发现还是挺容易上手的!
下载:
官网地址:https://mupdf.com/downloads/index.html (下载速度有点慢)
参考链接:http://labisart.com/blog/Upload/file/ueditor/202006/mupdf-1.17.0-source.tar.xz 这个链接下载速度比较快
编译:
下载之后解压,找到解决方案
打开解决方案,根据需要设置Debug/Release 版本,设置平台为x64
设置项目属性:libmupdf 和该项目依赖项的项目, Windows SDK版本,平台工具集,
只需要保证libmupdf项目生成成功即可。
编译完成之后,找到静态库文件
因为源码中没发现导出库,所以不能生成动态库Dll, 此时细心的你会发现静态库好大.....
调用:
1. 提取头文件和静态库文件(见上图路径):
2. 设置项目属性:C/C++ -> 附件包含目录、链接器 -> 附加库目录、链接器 -> 输入
3. 编写测试代码
test.cpp
#include <mupdf/fitz.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <SDKDDKVer.h>
bool PDF2PNG(std::string pdfFilePath, int pdfPageIdx, std::string outputPNGFilePath)
{
if (pdfFilePath.empty() || pdfPageIdx < 0)
{
return false;
}
//使用默认值
int pageCount = 0;
float zoom = 100;
float rotate = 0;
fz_context *ctx;
fz_document *doc;
fz_pixmap *pix;
fz_matrix ctm;
int x, y;
/* Create a context to hold the exception stack and various caches. */
ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
if (!ctx)
{
fprintf(stderr, "cannot create mupdf context\n");
return false;
}
/* Register the default file types to handle. */
fz_try(ctx)
{
fz_register_document_handlers(ctx);
}
fz_catch(ctx)
{
fprintf(stderr, "cannot register document handlers: %s\n", fz_caught_message(ctx));
fz_drop_context(ctx);
return false;
}
/* Open the document. */
fz_try(ctx)
{
doc = fz_open_document(ctx, pdfFilePath.c_str());
}
fz_catch(ctx)
{
fprintf(stderr, "cannot open document: %s\n", fz_caught_message(ctx));
fz_drop_context(ctx);
return false;
}
/* Count the number of pages. */
fz_try(ctx)
{
pageCount = fz_count_pages(ctx, doc);
}
fz_catch(ctx)
{
fprintf(stderr, "cannot count number of pages: %s\n", fz_caught_message(ctx));
fz_drop_document(ctx, doc);
fz_drop_context(ctx);
return false;
}
if (pdfPageIdx < 0 || pdfPageIdx >= pageCount)
{
fprintf(stderr, "page number out of range: %d (page count %d)\n", pdfPageIdx + 1, pageCount);
fz_drop_document(ctx, doc);
fz_drop_context(ctx);
return false;
}
/* Compute a transformation matrix for the zoom and rotation desired. */
/* The default resolution without scaling is 72 dpi. */
ctm = fz_scale(zoom / 100, zoom / 100);
ctm = fz_pre_rotate(ctm, rotate);
/* Render page to an RGB pixmap. */
fz_try(ctx)
{
pix = fz_new_pixmap_from_page_number(ctx, doc, pdfPageIdx, ctm, fz_device_rgb(ctx), 0);
}
fz_catch(ctx)
{
fprintf(stderr, "cannot render page: %s\n", fz_caught_message(ctx));
fz_drop_document(ctx, doc);
fz_drop_context(ctx);
return false;
}
fz_try(ctx)
{
fz_save_pixmap_as_png(ctx, pix, outputPNGFilePath.c_str());
}
fz_catch(ctx)
{
fz_drop_document(ctx, doc);
fz_drop_context(ctx);
return false;
}
/* Clean up. */
fz_drop_pixmap(ctx, pix);
fz_drop_document(ctx, doc);
fz_drop_context(ctx);
return true;
}
int main(int argc, char **argv)
{
std::string pdfFilePath = "C:\\Users\\think\\Desktop\\a.pdf";
std::string outputFilePath = "C:\\Users\\think\\Desktop\\a.png";
bool isOk = PDF2PNG(pdfFilePath, 0, outputFilePath);
return 0;
}
4. 因为静态库有点大,所以编译有点慢,至此完成。