跳到内容
  • 福昕首页
  • 开发中心
  • SDK文档资料
  • 福昕首页
  • 开发中心
  • SDK文档资料
申请试用
  • 企业自动化
    • Compressor
  • 福昕CloudAPI
  • 福昕PDF SDK 软件开发工具包
    • 福昕PDF SDK(ActiveX)
    • 福昕PDF SDK(桌面/服务器)
    • 福昕PDF SDK(Plug-in)
    • 福昕 PDF SDK(安卓)
    • 福昕PDF SDK(iOS)
    • 福昕PDF SDK(Web)
  • 福昕管理控制台
    • 公有云
    • 私有云
    • 通用情况
  • 福昕阅读器
    • RMS插件
  • 福昕高级编辑器
    • AI助手
    • Mac版本
      • 常规问题
    • windows版本
      • ECM集成
      • 互联PDF
      • 企业管理指南
      • 保护
      • 内容编辑
      • 创建PDF
      • 压缩
      • 图章
      • 安装与卸载
      • 常见问题
      • 打印
      • 注释/评论
      • 福昕插件
      • 翻译助手
      • 翻译助手教程
      • 试用与激活
      • 转换
      • 页面管理
    • 教育用户
      • 论文查重
      • 论文畅
    • 网页版
      • 电子签章
    • 订阅
    • 资源
  • 福昕高级编辑器Linux版本
  • 福船图纸管理系统
  • 福昕PDF SDK 软件开发工具包 > 福昕PDF SDK(Plug-in)
  • 标签:

如何为多个PDF页面同时添加注释?

  • 福昕知识库
  • 2024-07-24

如果您需要为一个在编辑器上已经打开的PDF的多个页面添加注释, 需要注意的事,开发包示例中的接口为FRPageViewAddAnnot(),只能对已加载过视图的(用户浏览过的)页面添加注释。如果要对还未加载的页面添加注释,可以使用FRDocAddAnnot()接口添加注释。

示例代码如下:

void CreateAnnot()
{
FS_FloatPoint pointLeftTop, pointRightBottom;
pointLeftTop.m_PointX = 100;
pointRightBottom.m_PointX = 400;
pointLeftTop.m_PointY = 200;
pointRightBottom.m_PointY=100;

FR_Document frDocument = FRAppGetActiveDocOfPDDoc();
FPD_Document fpdDocument = FRDocGetPDDoc(frDocument);
FR_DocView frDocView = FRDocGetCurrentDocView(frDocument);
FR_PageView frPageView = FRDocViewGetCurrentPageView(frDocView);

for (int i = 0; i < FPDDocGetPageCount(fpdDocument); i++)
{
FS_FloatRect rectFirst;
rectFirst.left = pointLeftTop.m_PointX;
rectFirst.right = pointRightBottom.m_PointX;;
rectFirst.bottom = pointRightBottom.m_PointY;
rectFirst.top = pointLeftTop.m_PointY;
FR_Annot frAnnot = FRDocAddAnnot(frDocument, i, "Stamp", rectFirst);
FPD_Annot fpdAnnot = FRAnnotGetPDFAnnot(frAnnot);

FR_Page frPage = FRDocGetPage(frDocument, i);

FPD_Page fpdPage = FPDPageNew();

FPD_Object pPageDict = FPDDocGetPage(fpdDocument, i);
FPDPageLoad(fpdPage, fpdDocument, pPageDict, TRUE);

FPD_Object fpdObject =
FPDAnnotGetAnnotDict(fpdAnnot);// FPDDictionaryNew();
//set subtype of the annot
FPD_Object fpdfstringAnnot = FPDNameNew("Annot");
FPDDictionaryAddValue(fpdObject, "Type", fpdfstringAnnot);
FPDDictionaryAddValue(fpdObject, "Subtype", FPDNameNew("Stamp"));
FPDDictionaryAddValue(fpdObject, "Subj", FPDStringNew(FSByteStringNew3("Stamp", -1), 0));


//set quadpoints of the annot
FPD_Object quad = FPDArrayNew(); //{x1, y1, x2, y2, x3, y3, x4, y5}
FPDArrayAddNumber(quad, rectFirst.left); //x1
FPDArrayAddNumber(quad, rectFirst.top);//y1
FPDArrayAddNumber(quad, rectFirst.right);//x2
FPDArrayAddNumber(quad, rectFirst.top);//y2
FPDArrayAddNumber(quad, rectFirst.left);//x3
FPDArrayAddNumber(quad, rectFirst.bottom);//y3
FPDArrayAddNumber(quad, rectFirst.right);//x4
FPDArrayAddNumber(quad, rectFirst.bottom);//y4
FPDDictionaryAddValue(fpdObject, "QuadPoints", quad);
FPDDictionaryAddValue(fpdObject, "NM", FPDNameNew("TextName"));

FPDDictionaryAddValue(fpdObject, "T", FPDNameNew("AuthorTest"));

FPD_Object quadColor = FPDArrayNew();
FS_COLORREF color = RGB(255, 215, 0);
//set color of the annot
FPDArrayAddNumber(quadColor, (FS_FLOAT)GetRValue(color) / 255.0f); //1 means RGB Color
FPDArrayAddNumber(quadColor, (FS_FLOAT)GetGValue(color) / 255.0f); //Defines the color
FPDArrayAddNumber(quadColor, (FS_FLOAT)GetBValue(color) / 255.0f); //Defines the color
FPDDictionaryAddValue(fpdObject, "C", quadColor);

FS_LPCWSTR ws = (FS_LPCWSTR)L"This is initial text";
FPD_Object fpdfstringPopout = FPDStringNewW(ws);
//set comment info of the annot
FPDDictionaryAddValue(fpdObject, "Contents", fpdfstringPopout);
//set BBox of the annot
FPDDictionarySetAtRect(fpdObject, "Rect", rectFirst);
auto pAPDict = FPDDictionaryGetDict(fpdObject, "AP");
if (pAPDict == nullptr)
{
pAPDict = FPDDictionarySetNewAt(fpdObject, "AP", FPD_OBJ_DICTIONARY);
}
FS_DWORD dwApObjNum = 0;
FS_DIBitmap pBitmap = FSDIBitmapLoadFromPNGIcon(L"D:\\test\\thumbnail_image001.png");
FPD_Object pObj = CreateAppearanceDict(fpdDocument, pBitmap, 0, &dwApObjNum);
FPDDictionarySetAtReferenceToDoc(pAPDict, "N", fpdDocument, dwApObjNum);
FPDDictionaryAddValue(fpdObject, "AP", pAPDict);

//将新增注释添加到侧边栏的注释列表中
if (frAnnot != NULL)
{
FR_MarkupPanel panel = FRMarkupPanelGetMarkupPanel();
if (panel)
{
FRMarkupPanelAddAnnot(panel, frAnnot, TRUE, TRUE);
}
}
}
//刷新当前页面,让注释显示
FRDocReloadPage(frDocument, FRPageViewGetPageIndex(FRDocViewGetCurrentPageView(frDocView)), FALSE);
}

上面这个示例是添加的"图章"注释,所以会用到。如果是其他类型注释例如"高亮"不一定需要下面的代码

//添加注释外观
FPD_Object CreateAppearanceDict(FPD_Document pdfDoc, FS_DIBitmap bitmap, int nRotate, FS_DWORD* pObjNum)
{
	if (!pdfDoc || !bitmap)
		return nullptr;
	FS_DWORD dwNewObjNumber = 0;
	FPD_Object apperenceDict = FPDDictionaryNew();

	FS_AffineMatrix streamMatrix;
	switch (nRotate)
	{
	case 0:
	{
		streamMatrix.a = 1.0f;
		streamMatrix.b = 0.0f;
		streamMatrix.c = 0.0f;
		streamMatrix.d = 1.0f;
	}
	break;
	case 90:
	{
		streamMatrix.a = 0.0f;
		streamMatrix.b = 1.0f;
		streamMatrix.c = -1.0f;
		streamMatrix.d = 0.0f;
	}
	break;
	case 180:
	{
		streamMatrix.a = -1.0f;
		streamMatrix.b = 0.0f;
		streamMatrix.c = 0.0f;
		streamMatrix.d = -1.0f;
	}
	break;
	case 270:
	{
		streamMatrix.a = 0.0f;
		streamMatrix.b = -1.0f;
		streamMatrix.c = 1.0f;
		streamMatrix.d = 0.0f;
	}
	break;
	default:
		break;
	}
	streamMatrix.e = 0;
	streamMatrix.f = 0;
	FPDDictionarySetAtMatrix(apperenceDict, "Matrix", streamMatrix);
	FPD_Object resourcesDict = FPDDictionaryNew();
	FPD_Object xObject = FPDDictionaryNew();

	FPD_Image image = FPDImageNew(pdfDoc);
	//ON_SCOPE_EXIT([&] {

	//});
	FPDImageSetImage(image, bitmap, FALSE, nullptr);
	FPD_Object imgStream = FPDImageGetStream(image);
	if (imgStream)
	{
		dwNewObjNumber = FPDDocAddIndirectObject(pdfDoc, imgStream);
		FPDDictionarySetAtReferenceToDoc(xObject, "ImgSignature", pdfDoc, dwNewObjNumber);
	}
	FPDDictionarySetAt(resourcesDict, "XObject", xObject, nullptr);

	FPD_Object extGStateDict = FPDDictionaryNew();
	FPDDictionarySetAtNumber(extGStateDict, "CA", 1);
	FPDDictionarySetAtNumber(extGStateDict, "ca", 1);
	FS_DWORD dwNewExtGStateObjNumber = FPDDocAddIndirectObject(pdfDoc, extGStateDict);
	FPD_Object extGStateDictRef = FPDDictionaryNew();
	FPDDictionarySetAtReferenceToDoc(extGStateDictRef, "FXE1", pdfDoc, dwNewExtGStateObjNumber);
	FPDDictionarySetAt(resourcesDict, "ExtGState", extGStateDictRef, nullptr);

	FPDDictionarySetAt(apperenceDict, "Resources", resourcesDict, nullptr);

	int bmpWidth = FSDIBitmapGetWidth(bitmap);
	int bmpHeight = FSDIBitmapGetHeight(bitmap);

	FPD_Object streamBBox = FPDArrayNew();
	FPDArrayAddNumber(streamBBox, 0);
	FPDArrayAddNumber(streamBBox, 0);
	FPDArrayAddNumber(streamBBox, bmpWidth);
	FPDArrayAddNumber(streamBBox, bmpHeight);


	FPDDictionarySetAt(apperenceDict, "BBox", streamBBox, nullptr);
	FPDDictionarySetAtName(apperenceDict, "Type", "XObject");
	FPDDictionarySetAtName(apperenceDict, "Subtype", "Form");

	FS_ByteString apStreamData = FSByteStringNew();

	FSByteStringFormat(apStreamData, "q\n/FXE1 gs\n%d 0 0 %d 0 0 cm\n/ImgSignature Do\nQ", bmpWidth, bmpHeight);

	auto pNewContents = FPDStreamNew();
	FPDStreamInitStream(pNewContents, NULL, 0, apperenceDict);
	FPDStreamSetData(pNewContents, (FS_LPBYTE)FSByteStringCastToLPCBYTE(apStreamData),
		FSByteStringGetLength(apStreamData), FALSE, FALSE);
	auto dwObjNum = FPDDocAddIndirectObject(pdfDoc, pNewContents);
	if (pObjNum)
		*pObjNum = dwObjNum;

	FSByteStringDestroy(apStreamData);
	FPDImageDestroy(image);
	return pNewContents;
}

效果如下:

相关内容

PDF打印时,如何在每张纸上放置多页?

扫描件如何转为可编辑的Word?

如何批量OCR文档?

PDF文档中如何添加下划线?

如何在PDF中添加超链接?

如何使用PDF把彩色图片转为灰度图?

安装报“无法安装Foxit PDF Editor Printer Driver 内核模式打印驱动程序……”

outlook邮件使用福昕转换的pdf打开提示为文件包

如何关闭受保护视图

使用OCR文本识别提示下载对应语言识别插件

推荐内容

PDF打印时,如何在每张纸上放置多页?

扫描件如何转为可编辑的Word?

如何批量OCR文档?

PDF文档中如何添加下划线?

如何在PDF中添加超链接?

如何使用PDF把彩色图片转为灰度图?

安装报“无法安装Foxit PDF Editor Printer Driver 内核模式打印驱动程序……”

outlook邮件使用福昕转换的pdf打开提示为文件包

如何关闭受保护视图

使用OCR文本识别提示下载对应语言识别插件

产品
  • 应用行业
  • 白皮书
开发支持
  • 开发中心
  • SDK文档资料

销售咨询:010-50951668

客服电话:0591-38509808

销售咨询
微信公众号

©2025 福建福昕软件开发股份有限公司 版权所有

隐私策略