OFD 文档水印
本节介绍在 OFD 页面上添加文本或图片水印。水印通过 Watermark 绑定 OFDPage 后,按绝对坐标、对齐、平铺、区域或多区域等方式叠加到页面内容中。取得 OFDPage 请参阅 OFD 文档与页面。
任务场景
- 在指定
OFDPage上添加文本或图片水印(AddTextWatermark/AddImageWatermark)。 - 按页面对齐方式放置水印,无需手动计算坐标(
AddAlign*Watermark)。 - 在整页或指定
RectF区域内平铺水印(AddTiled*Watermark/AddRegion*Watermark)。 - 按水平/垂直网格划分页面并批量添加水印(
AddMultiArea*Watermark)。 - 图片水印前先将图像嵌入文档并取得
image_id(OFDDoc::AddImageResourceFromFile)。 - 多页文档逐页创建
Watermark(page),添加后通过OFDPackage::Save/SaveAs持久化。
API 概览
| 功能 | C++ API(foxit::ofd) | 核心参数 / 描述 |
|---|---|---|
| 水印操作 | Watermark | 构造绑定 OFDPage;提供各类 Add*Watermark 方法 |
| 文本内容 | TextProperties | text、font_name、font_size(毫米)、char_space、text_color(RGB 整型,如 0xFF0000) |
| 图片内容 | ImageProperties | image_id:文档内图像资源 ID(须先 AddImageResourceFromFile 等) |
| 绝对位置布局 | WatermarkSettings | x_pos、y_pos(毫米)、width、height、rotation(0–360°)、opacity(0–255) |
| 对齐布局 | AlignmentWatermarkSettings | h_align、v_align(左/中/右,上/中/下)及尺寸、旋转、透明度 |
| 平铺布局 | TiledWatermarkSettings | 继承 WatermarkSettings;x_step、y_step(毫米,须 > 0) |
| 区域范围 | foxit::RectF | left、bottom、right、top(OFD 坐标系) |
| 文本水印 | AddTextWatermark、AddAlignTextWatermark、AddTiledTextWatermark、AddRegionTextWatermark、AddMultiAreaTextWatermark | 按布局方式添加文字水印 |
| 图片水印 | AddImageWatermark、AddAlignImageWatermark、AddTiledImageWatermark、AddRegionImageWatermark、AddMultiAreaImageWatermark | 按布局方式添加图片水印 |
| 持久化 | OFDPackage::Save、SaveAs | 水印写入页面后须保存文件包 |
添加文本水印
定义 TextProperties 描述文字内容与样式,再用 WatermarkSettings 指定位置(毫米)、尺寸、旋转角与透明度,调用 AddTextWatermark。
c++
#include "ofd/fs_ofdpackage.h"
#include "ofd/fs_ofddoc.h"
#include "ofd/fs_ofdpage.h"
#include "ofd/watermark/fs_ofdwatermark.h"
using namespace foxit;
using namespace foxit::ofd;
bool AddTextWatermarkToPage(OFDPage& page) {
if (page.IsEmpty()) {
return false;
}
Watermark watermark(page);
// 文本:内容、字体、字号(毫米)、字间距、颜色
TextProperties text_props("机密", "SimSun", 14.0f, 0.5f, 0xFF0000);
if (!text_props.IsValid()) {
return false;
}
// 布局:x/y(毫米)、宽、高、旋转角、透明度(0–255)
WatermarkSettings settings(15.0f, 20.0f, 90.0f, 20.0f, 15.0f, 160, true, true);
if (!settings.IsValid()) {
return false;
}
return watermark.AddTextWatermark(text_props, settings);
}
java
import com.foxit.sdk.ofd.OFDPage;
import com.foxit.sdk.ofd.watermark.TextProperties;
import com.foxit.sdk.ofd.watermark.Watermark;
import com.foxit.sdk.ofd.watermark.WatermarkSettings;
public class OFDTextWatermarkExample {
public static boolean addTextWatermarkToPage(OFDPage page) throws Exception {
if (page.isEmpty()) {
return false;
}
Watermark watermark = new Watermark(page);
// 文本:内容、字体、字号(毫米)、字间距、颜色(RGB 整型值)
TextProperties textProps = new TextProperties(
"机密", "SimSun", 14.0f, 0.5f, 0xFF0000L);
if (!textProps.isValid()) {
return false;
}
// 布局:x/y(毫米)、宽、高、旋转角、透明度(0–255)
WatermarkSettings settings = new WatermarkSettings(
15.0f, 20.0f, 90.0f, 20.0f, 15.0f, (short) 160, true, true);
if (!settings.isValid()) {
return false;
}
return watermark.addTextWatermark(textProps, settings);
}
}
添加图片水印
图片水印使用 ImageProperties(image_id)。image_id 须为已通过 OFDDoc::AddImageResourceFromFile 等接口嵌入文档的有效资源 ID,不能直接使用本地文件路径;资源嵌入流程请参阅 元数据、资源与自定义数据。
c++
#include "ofd/fs_ofddoc.h"
#include "ofd/fs_ofdpage.h"
#include "ofd/watermark/fs_ofdwatermark.h"
using namespace foxit;
using namespace foxit::ofd;
bool AddImageWatermarkToPage(OFDDoc& doc, OFDPage& page, const wchar_t* image_path) {
if (doc.IsEmpty() || page.IsEmpty()) {
return false;
}
// 先将图像嵌入文档,取得资源 ID
uint32 image_id = doc.AddImageResourceFromFile(WString(image_path));
if (image_id == 0) {
return false;
}
Watermark watermark(page);
ImageProperties image_props(image_id);
if (!image_props.IsValid()) {
return false;
}
WatermarkSettings settings(20.0f, 26.0f, 42.0f, 18.0f, 12.0f, 180, true, true);
return watermark.AddImageWatermark(image_props, settings);
}
java
import com.foxit.sdk.ofd.OFDDoc;
import com.foxit.sdk.ofd.OFDPage;
import com.foxit.sdk.ofd.watermark.ImageProperties;
import com.foxit.sdk.ofd.watermark.Watermark;
import com.foxit.sdk.ofd.watermark.WatermarkSettings;
public class OFDImageWatermarkExample {
public static boolean addImageWatermarkToPage(OFDDoc doc, OFDPage page,
String imagePath) throws Exception {
if (doc.isEmpty() || page.isEmpty()) {
return false;
}
// 先将图像嵌入文档,取得资源 ID
int imageId = doc.addImageResourceFromFile(imagePath);
if (imageId == 0) {
return false;
}
Watermark watermark = new Watermark(page);
ImageProperties imageProps = new ImageProperties(imageId);
if (!imageProps.isValid()) {
return false;
}
WatermarkSettings settings = new WatermarkSettings(
20.0f, 26.0f, 42.0f, 18.0f, 12.0f, (short) 180, true, true);
return watermark.addImageWatermark(imageProps, settings);
}
}
对齐水印
使用 AlignmentWatermarkSettings 按页面水平/垂直对齐方式放置水印,无需手动计算绝对坐标。
c++
#include "ofd/watermark/fs_ofdwatermark.h"
using namespace foxit;
using namespace foxit::ofd;
bool AddAlignedTextWatermark(OFDPage& page) {
if (page.IsEmpty()) {
return false;
}
Watermark watermark(page);
TextProperties text_props("DRAFT", "SimHei", 12.0f, 0.3f, 0x808080);
// 水平居中、垂直居中
AlignmentWatermarkSettings align_settings(
AlignmentWatermarkSettings::e_WatermarkHAlignCenter,
AlignmentWatermarkSettings::e_WatermarkVAlignMiddle,
70.0f, 18.0f, 30.0f, 100);
return watermark.AddAlignTextWatermark(text_props, align_settings);
}
java
import com.foxit.sdk.ofd.OFDPage;
import com.foxit.sdk.ofd.watermark.AlignmentWatermarkSettings;
import com.foxit.sdk.ofd.watermark.TextProperties;
import com.foxit.sdk.ofd.watermark.Watermark;
public class OFDAlignWatermarkExample {
public static boolean addAlignedTextWatermark(OFDPage page) throws Exception {
if (page.isEmpty()) {
return false;
}
Watermark watermark = new Watermark(page);
TextProperties textProps = new TextProperties(
"DRAFT", "SimHei", 12.0f, 0.3f, 0x808080L);
// 水平居中、垂直居中
AlignmentWatermarkSettings alignSettings = new AlignmentWatermarkSettings(
AlignmentWatermarkSettings.e_WatermarkHAlignCenter,
AlignmentWatermarkSettings.e_WatermarkVAlignMiddle,
70.0f, 18.0f, 30.0f, (short) 100);
return watermark.addAlignTextWatermark(textProps, alignSettings);
}
}
平铺水印
TiledWatermarkSettings 在 WatermarkSettings 基础上增加 x_step、y_step,控制平铺间距,常用于背景底纹。
c++
#include "ofd/watermark/fs_ofdwatermark.h"
using namespace foxit;
using namespace foxit::ofd;
bool AddTiledTextWatermark(OFDPage& page) {
if (page.IsEmpty()) {
return false;
}
Watermark watermark(page);
TextProperties text_props("TILED", "KaiTi", 11.0f, 0.4f, 0x0000FF);
// x_step、y_step 为平铺步长(毫米),须大于 0
TiledWatermarkSettings tiled_settings(
10.0f, 10.0f, 45.0f, 12.0f, 25.0f, 90, 55.0f, 40.0f, true, false);
return watermark.AddTiledTextWatermark(text_props, tiled_settings);
}
java
import com.foxit.sdk.ofd.OFDPage;
import com.foxit.sdk.ofd.watermark.TextProperties;
import com.foxit.sdk.ofd.watermark.TiledWatermarkSettings;
import com.foxit.sdk.ofd.watermark.Watermark;
public class OFDTiledWatermarkExample {
public static boolean addTiledTextWatermark(OFDPage page) throws Exception {
if (page.isEmpty()) {
return false;
}
Watermark watermark = new Watermark(page);
TextProperties textProps = new TextProperties(
"TILED", "KaiTi", 11.0f, 0.4f, 0x0000FFL);
// xStep、yStep 为平铺步长(毫米),须大于 0
TiledWatermarkSettings tiledSettings = new TiledWatermarkSettings(
10.0f, 10.0f, 45.0f, 12.0f, 25.0f, (short) 90,
55.0f, 40.0f, true, false);
return watermark.addTiledTextWatermark(textProps, tiledSettings);
}
}
区域与多区域水印
在指定矩形区域内平铺水印,或按水平/垂直网格划分页面后批量添加。
c++
#include "common/fs_common.h"
#include "ofd/watermark/fs_ofdwatermark.h"
using namespace foxit;
using namespace foxit::ofd;
bool AddRegionAndMultiAreaWatermarks(OFDPage& page) {
if (page.IsEmpty()) {
return false;
}
Watermark watermark(page);
// 区域平铺:平铺仅在 RectF 范围内生效
RectF region(20.0f, 120.0f, 140.0f, 20.0f);
TextProperties region_text("REGION", "SimSun", 10.0f, 0.2f, 0x00AA00);
TiledWatermarkSettings region_tiled(
0.0f, 0.0f, 20.0f, 10.0f, 35.0f, 120, 35.0f, 25.0f);
if (!watermark.AddRegionTextWatermark(region, region_text, region_tiled)) {
return false;
}
// 多区域:水平 2 列、垂直 3 行网格
TextProperties multi_text("MULTI", "SimHei", 9.0f, 0.1f, 0xAA5500);
WatermarkSettings multi_settings(0.0f, 0.0f, 30.0f, 10.0f, 45.0f, 100);
return watermark.AddMultiAreaTextWatermark(2, 3, multi_text, multi_settings);
}
java
import com.foxit.sdk.common.fxcrt.RectF;
import com.foxit.sdk.ofd.OFDPage;
import com.foxit.sdk.ofd.watermark.TextProperties;
import com.foxit.sdk.ofd.watermark.TiledWatermarkSettings;
import com.foxit.sdk.ofd.watermark.Watermark;
import com.foxit.sdk.ofd.watermark.WatermarkSettings;
public class OFDRegionWatermarkExample {
public static boolean addRegionAndMultiAreaWatermarks(OFDPage page)
throws Exception {
if (page.isEmpty()) {
return false;
}
Watermark watermark = new Watermark(page);
// 区域平铺:平铺仅在 RectF 范围内生效
RectF region = new RectF(20.0f, 120.0f, 140.0f, 20.0f);
TextProperties regionText = new TextProperties(
"REGION", "SimSun", 10.0f, 0.2f, 0x00AA00L);
TiledWatermarkSettings regionTiled = new TiledWatermarkSettings(
0.0f, 0.0f, 20.0f, 10.0f, 35.0f, (short) 120, 35.0f, 25.0f);
if (!watermark.addRegionTextWatermark(region, regionText, regionTiled)) {
return false;
}
// 多区域:水平 2 列、垂直 3 行网格
TextProperties multiText = new TextProperties(
"MULTI", "SimHei", 9.0f, 0.1f, 0xAA5500L);
WatermarkSettings multiSettings = new WatermarkSettings(
0.0f, 0.0f, 30.0f, 10.0f, 45.0f, (short) 100);
return watermark.addMultiAreaTextWatermark(2, 3, multiText, multiSettings);
}
}
保存与预览
水印添加后调用 OFDPackage::Save 或 SaveAs 写回文件。预览带水印效果可结合 OFD 渲染 将页面渲染为位图查看。
c++
#include "ofd/fs_ofdpackage.h"
using namespace foxit::ofd;
bool SaveWatermarkedDocument(OFDPackage& package, const wchar_t* output_path) {
if (package.IsEmpty()) {
return false;
}
// 水印修改页面内容后须包层保存
return package.SaveAs(WString(output_path));
}
java
import com.foxit.sdk.ofd.OFDPackage;
public class OFDSaveWatermarkExample {
public static boolean saveWatermarkedDocument(OFDPackage pkg,
String outputPath) throws Exception {
if (pkg.isEmpty()) {
return false;
}
// 水印修改页面内容后须包层保存
return pkg.saveAs(outputPath);
}
}
注意事项
- 页面级操作:
Watermark绑定OFDPage,多页文档须逐页创建并添加;无文档级一次性全局接口。 - 图片资源 ID:
ImageProperties的image_id须为OFDDoc::AddImageResourceFromFile等返回的有效 ID(非 0);详见 元数据、资源与自定义数据。 - 单位与范围:位置与尺寸单位为毫米;
rotation为 0–360(不含 360);opacity为 0–255;平铺x_step/y_step须大于 0。 - 坐标系:
WatermarkSettings的x_pos/y_pos及RectF区域使用 OFD 坐标系,添加前请确认原点与轴向,避免位置偏差。 - 区域平铺:
AddRegion*Watermark的平铺仅在指定RectF内生效,超出区域部分不绘制。 - 性能与体积:步长过小的平铺水印会显著增加图元数量,可能导致文件体积增大或渲染变慢,请按实际需求调整密度。