因PDF文档具有较好的稳定性和兼容性,现在越来越多的合同、研究论文、报告等都采用PDF格式。为了进一步保护这些重要文档内容免受未经授权的复制或使用,我们可以添加水印以表明其状态、所有权或用途。针对工作中可能出现的在 C++ 应用程序中给 PDF 文档添加文字水印的需求,本文将详细展示如何通过第三方国产库Spire.PDF for C++来实现这一功能。

安装 : Spire.PDF for C++是一款国产独立 PDF 控件,可实现 C++ 程序中创建、读取、操作、编辑和转换 PDF 文档。推荐的安装方式是在Visual Studio 中通过NuGet搜索 “spire.pdf.cpp”,然后点击下载将其安装到程序中。或者下载 Spire.PDF for C++ 到本地,解压后手动将库复制到程序中。

在 PDF 文档中添加单行文字水印

Spire.PDF for C++ 没有提供直接在PDF中插入水印的接口或类,但可以通过在PDF页面上绘制文本并设置其透明度来模拟添加文字水印的效果。主要步骤如下:

  1. 创建 PdfDocument 对象。
  2. 使用 PdfDocument->LoadFromFile() 方法加载示例 PDF 文档。
  3. 使用 PdfDocument->GetPages()->GetItem() 方法获取档中的特定页面。
  4. 使用 PdfPageBase->GetCanvas()->TraslateTransform() 方法将页面坐标系平移至指定位置。
  5. 使用 PdfPageBase->GetCanvas()->RotateTransform() 方法将坐标系旋转指定角度。(第四五步是为了确保水印以指定角度显示在页面中心位置。
  6. 使用 PdfPageBase->GetCanvas()->DrawString() 方法在PDF页面上绘制文本水印。
  7. 使用 PdfDocument->SaveToFile() 方法保存结果文档。

C++代码:

#include "Spire.Pdf.o.h";

using namespace std;
using namespace Spire::Pdf; int main()
{ //创建PdfDocument对象
intrusive_ptr <PdfDocument> doc = new PdfDocument(); //加载PDF文件
doc->LoadFromFile(L"协议.pdf"); //创建TrueType字体
intrusive_ptr <PdfTrueTypeFont> font = new PdfTrueTypeFont(L"黑体", 60.0f, PdfFontStyle::Bold, true); //创建笔刷
intrusive_ptr <PdfBrush> brush = PdfBrushes::GetSkyBlue(); //指定水印文本
wstring text = L"内部文件"; //测量水印文本大小
SizeF textSize = font->MeasureString(text.c_str()); //计算两个偏移量,用于计算坐标系的平移量
float offset1 = (float)(textSize.GetWidth() * sqrt(2) / 4);
float offset2 = (float)(textSize.GetHeight() * sqrt(2) / 4); //遍历文档中的页面
for (size_t i = 0; i < doc->GetPages()->GetCount(); i++)
{
//获取指定页面
intrusive_ptr <PdfPageBase> page = doc->GetPages()->GetItem(i); //设置透明度
page->GetCanvas()->SetTransparency(0.8); //将页面坐标系平移至指定位置
page->GetCanvas()->TranslateTransform(page->GetCanvas()->GetSize()->GetWidth() / 2 - offset1 - offset2, page->GetCanvas()->GetSize()->GetHeight() / 2 + offset1 - offset2); //逆时针旋转坐标系45度
page->GetCanvas()->RotateTransform(-45); //在页面上绘制水印
page->GetCanvas()->DrawString(text.c_str(), font, brush, 0, 0, new PdfStringFormat(PdfTextAlignment::Left));
} //保存结果文档
doc->SaveToFile(L"Output\\文字水印.pdf");
doc->Close();
}

单行水印效果:

在 PDF 文档中添加多行文字水印

使用Spire.PDF for C++提供的 PdfTilingBrush 类可以实现平铺水印效果。平铺笔刷会生成一个平铺图案,用它重复填充指定图形区域即可在 PDF 文档中添加多行水印。主要步骤如下:

  1. 创建自定义方法 InsertTiledTextWatermark(intrusive_ptr <PdfPageBase> page, wstring watermarkText, intrusive_ptr <PdfTrueTypeFont> font, int rowNum, int columnNum)来为 PDF 页面添加平铺水印。(其中参数 rowNum 和 columnNum 指定平铺水印的行数和列数)。
  2. 创建 PdfDocument 对象。
  3. 使用 PdfDocument->LoadFromFile() 方法加载 PDF 示例文档。
  4. 遍历文档中的所有页面,并调用自定义方法 InsertTiledTextWatermark() 将水印添加到每一页。
  5. 使用PdfDocument->SaveToFile()方法保存结果文档。

C++代码:

#include "Spire.Pdf.o.h";

using namespace std;
using namespace Spire::Pdf; static void InsertTiledTextWatermark(intrusive_ptr <PdfPageBase> page, wstring watermarkText, intrusive_ptr <PdfTrueTypeFont> font, int rowNum, int columnNum)
{
//测量水印文本大小
SizeF textSize = font->MeasureString(watermarkText.c_str()); //计算两个偏移量,用于计算坐标系的平移量
float offset1 = (float)(textSize.GetWidth() * sqrt(2) / 4);
float offset2 = (float)(textSize.GetHeight() * sqrt(2) / 4); //获取页面高度和宽度
float height = page->GetActualSize()->GetHeight();
float width = page->GetActualSize()->GetWidth(); //创建平铺笔刷
intrusive_ptr <PdfTilingBrush> brush = new PdfTilingBrush(new SizeF(width / columnNum, height / rowNum));
brush->GetGraphics()->SetTransparency(0.3f);
brush->GetGraphics()->TranslateTransform(brush->GetSize()->GetWidth() / 2 - offset1 - offset2, brush->GetSize()->GetHeight() / 2 + offset1 - offset2);
brush->GetGraphics()->RotateTransform(-45); //在笔刷上绘制水印文字
brush->GetGraphics()->DrawString(watermarkText.c_str(), font, PdfBrushes::GetRed(), 0, 0, new PdfStringFormat(PdfTextAlignment::Left)); //使用平铺笔刷绘制一个覆盖整个页面的矩形
page->GetCanvas()->DrawRectangle(brush, new RectangleF(new PointF(0, 0), page->GetActualSize()));
} int main()
{ //创建PdfDocument对象
intrusive_ptr <PdfDocument> doc = new PdfDocument(); //加载PDF文件
doc->LoadFromFile(L"协议.pdf"); //指定水印文本
wstring text = L"内部文件"; //创建TrueType字体
intrusive_ptr <PdfTrueTypeFont> font = new PdfTrueTypeFont(L"黑体", 30.0f, PdfFontStyle::Bold, true); //遍历文档中的页面
for (size_t i = 0; i < doc->GetPages()->GetCount(); i++)
{
//调用自定义方法来插入多行文本水印
InsertTiledTextWatermark(doc->GetPages()->GetItem(i), text.c_str(), font, 3, 3);
} //保存结果文件
doc->SaveToFile(L"Output\\多行水印.pdf");
doc->Close();
}

多行水印效果:

此外还可参考:C++给PDF文档添添加图片水印

如何通过C++ 给PDF文档添加文字水印的更多相关文章

  1. 利用iTextSharp组件给PDF文档添加图片水印,文字水印

    最近在做关于PDF文档添加水印的功能,折腾了好久,终于好了.以下做个记录: 首先会用到iTextSharp组件,大家可以去官网下载,同时我也会在本文中附加进来. 代码中添加引用为:   using S ...

  2. C#给PDF文档添加文本和图片页眉

    页眉常用于显示文档的附加信息,我们可以在页眉中插入文本或者图形,例如,页码.日期.公司徽标.文档标题.文件名或作者名等等.那么我们如何以编程的方式添加页眉呢?今天,这篇文章向大家分享如何使用了免费组件 ...

  3. C#如何给PDF文档添加注释

    整理文档时,我们可能会需要在一些或一段文字上添加注释加以说明,那如何以编程的方式实现呢?本文将实例讲述C#中如何使用免费组件给PDF文档添加文本注释,包括自由文本注释.自由文本注释能允许我们自定义它的 ...

  4. C# 给现有PDF文档添加页眉、页脚

    概述 页眉页脚是一篇完整.精致的文档的重要组成部分.在页眉页脚处,可以呈现的内容很多,如公司名称.页码.工作表名.日期.图片,如LOGO.标记等.在之前的文章中介绍了如何通过新建一页空白PDF页来添加 ...

  5. 如何给PDF文档添加和删除贝茨编号

    PDF文件的使用频率高了,我们也不只局限于使用PDF文件了,也会需要编辑PDF文件的时候,那么如何在PDF文件中添加和去除贝茨编号呢,应该有很多小伙伴都想知道吧,今天就来跟大家分享一下吧,小伙伴们就一 ...

  6. ABBYY FineReader 15 如何为PDF文档添加页眉页脚

    页眉.页脚是文档页面顶部或底部重复出现的文本信息.很多用户会习惯在文档页面的顶部与底部区域添加页眉.页脚来展现页码.文档标题.作者姓名.品牌名称等附加信息.而ABBYY FineReader 15(W ...

  7. OpenXml入门----给Word文档添加文字

    使用OpenXml给word文档添加文字,每个模块都有自己对于的属性以及内容,要设置样式就先声明属性对象,将样式Append到属性里面,再将属性append到模块里面,那么模块里面的内容就具备该样式了 ...

  8. 「Python实用秘技04」为pdf文件批量添加文字水印

    本文完整示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/PythonPracticalSkills 这是我的系列文章「Python实用秘技」的第4期 ...

  9. 如何在PDF文档上加水印

    当我们需要传输一些比较重要的文件时,往往会选择将文档转换为PDF文件,避免其他人复制.更改文档的内容. pdfFactory不仅可以为用户提供快速创建PDF的功能,同时还提供了添加水印的功能.有了水印 ...

  10. Java 插入附件到PDF文档

    在文档中插入附件,可以起到与源文档配套使用的目的,以一种更简便的方式对文档起到补充说明的作用.下面将介绍通过Java编程插入附件到PDF文档中的方法.这里插入的文档可以是常见的文档类型,如Word.E ...

随机推荐

  1. linux系统下python中的tkinter库

    打开终端,输入如下命令: sudo apt-get update sudo apt-get install python3-tk

  2. 让nodejs开启服务更简单--koa篇

    在nodejs原始的http模块中,开启一个服务编码相对麻烦,需要对请求方式及上传的数据进行各种判断,而koa给我们提供了比较便捷的编码方式,同时它还有很多中间件可以直接拿来使用.   首先来看,如何 ...

  3. Prompt Playground 7月开发记录(2): Avalonia 应用开发

    Prompt Playground 7月开发记录(2): Avalonia 应用开发 仅以此文记录开发过程中遇到的问题和个人的解决方案,如若有理解偏差或者更好的解决方案,欢迎指正. 客户端的开发的确不 ...

  4. PXE操作过程 kickstart 无人值守安装

    PXE操作过程 分配给同一局域网内新加机器的地址(配置文件) dhcp 分配地址 指明tftp 服务器的地址 tftp服务端开启 udp 配置 默认关闭 安装syslinux 取得 pxelinux. ...

  5. ShardingSphere实战

    前言 本文主要从sharding最新版本5.1.2版本入手搭建,按主键ID和时间进行分表. 本文主要介绍搭建过程,有兴趣了解shardingsphere的同学可以先自行查阅相关资料. shardsph ...

  6. HDFS核心概念与架构

    HDFS简介 HDFS是Hadoop项目的核心子项目,在大数据开发中通过分布式计算对海量数据进行存储与管理,它基于流数据模式访问和处理超大文件的需求而开发,可以运行在廉价的商用服务器上,为海量数据提供 ...

  7. 分布式环境下Session共享问题解决和原理讲解

    1.分布式环境下Session共享问题: 2.几种解决方法 3.通过后端统一存储方法在实际项目中问题的体现: 当session的作用域只限于auth.gulimall.com时,在auth.gulim ...

  8. 【NET 7.0、OpenGL ES】使用Silk.NET渲染MMD,并实时进行物理模拟。

    有关mmd播放器,网上也有许多非常漂亮的实现,如 pmxeditor.saba.blender_mmd_tools等等.. 首先我想先介绍下我参考实现的仓库: sselecirPyM/Coocoo3D ...

  9. Dubbo3应用开发——架构的演变过程

    Dubbo3应用开发--架构的演变过程 什么是Dubbo 早期Dubbo的定位: 基于Java的高性能,轻量级的RPC框架:SOA[Service-Oriented Architecture ⾯向服务 ...

  10. Solution -「九省联考 2018」劈配

    Description Link. 一年一度的综艺节目<中国新代码>又开始了.Zayid 从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了. 轻车熟路的 Za ...