近期使用PDFium做了一下关于PDF的渲染,提取文本,提取图片等测试。
其中图片貌似能完整提取出来,如果用FPDFImageObj_GetRenderedBitmap返回NULL,可以考虑再用FPDFImageObj_GetBitmap补刀,从文档上看FPDFImageObj_GetBitmap得到的位图可能还要对矩阵信息处理。其中测试到一个PDF,在PDF阅读器上完全看不到,但是却能导出来图片,于是找啊找,发现mark是对象类型为“OCG”的建议隐藏(在PDFium读出来是“OC”,我在MAC下使用系统解释器看到的是OCG),这样一来只需要将包含这个类型的mark对应的object跳过即可。
用到的接口:
//下面代码不是全部,仅将要点记录一下。
FPDF_PAGEOBJECTMARK mask = FPDFPageObj_GetMark(pobj,i);
FPDFPageObjMark_GetParamKey(mask, j, buffer, 1024, &out_len);
/*
key => ["Intent",
"Name", //这里是mark的名称,如“图层 1”等
"Type", //这里是层的类型 如“OCG”
"Usage"]
*/
FPDF_OBJECT_TYPE type = FPDFPageObjMark_GetParamValueType(mask, key);
//type = FPDF_OBJECT_STRING (3)
FPDFPageObjMark_GetParamStringValue(mask, key, buffer, 1024, &out_len);
//type = FPDF_OBJECT_NAME (4) 这里有点困惑,在MAC下读取NAME类型的可以直接用string,但是PDFium是不能用FPDFPageObjMark_GetParamStringValue读NAME类型的,我没找到其他的接口,只能选择FPDFPageObjMark_GetName作为判断依据。
FPDFPageObjMark_GetName(mask, buffer, 1024, &out_len);
20220330 补充:
用OC不能判断是否隐藏,这个是所谓的可选项,但是在PDF1.6后用的比较频繁,要是将OC的对象都丢弃,拆解出来的图片会少很多,包括一些能显示的。应该用另外一个参数判断的,不过PDFium库没找到相应的接口。
20220429 关于判断显示的逻辑(源码有提到,可惜没在公开的接口找到,最好能自己编译将接口引出来)
//这段是我随手写的,测试过可以用,没条件编译源码的就忽略吧。
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDF_isObjectVisible(FPDF_DOCUMENT document,FPDF_PAGEOBJECT pageobj) {
CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
if (!pDoc)
return 0;
const CPDF_Dictionary* pRoot = pDoc->GetRoot();
if (!pRoot)
{
return 0;
}
CPDF_PageObject *pobj = CPDFPageObjectFromFPDFPageObject(pageobj);
RetainPtr<CPDF_OCContext> m_pOCContext=(RetainPtr<CPDF_OCContext>)pdfium::MakeRetain<CPDF_OCContext>(pDoc, CPDF_OCContext::kView);
return m_pOCContext->CheckObjectVisible(pobj);
}