Skip to content

OFD 文档水印

本节介绍在 OFD 页面上添加文本或图片水印。水印通过 Watermark 绑定 OFDPage 后,按绝对坐标、对齐、平铺、区域或多区域等方式叠加到页面内容中。取得 OFDPage 请参阅 OFD 文档与页面

任务场景

  • 在指定 OFDPage 上添加文本或图片水印(AddTextWatermark / AddImageWatermark)。
  • 按页面对齐方式放置水印,无需手动计算坐标(AddAlign*Watermark)。
  • 在整页或指定 RectF 区域内平铺水印(AddTiled*Watermark / AddRegion*Watermark)。
  • 按水平/垂直网格划分页面并批量添加水印(AddMultiArea*Watermark)。
  • 图片水印前先将图像嵌入文档并取得 image_idOFDDoc::AddImageResourceFromFile)。
  • 多页文档逐页创建 Watermark(page),添加后通过 OFDPackage::Save / SaveAs 持久化。

API 概览

功能C++ API(foxit::ofd核心参数 / 描述
水印操作Watermark构造绑定 OFDPage;提供各类 Add*Watermark 方法
文本内容TextPropertiestextfont_namefont_size(毫米)、char_spacetext_color(RGB 整型,如 0xFF0000
图片内容ImagePropertiesimage_id:文档内图像资源 ID(须先 AddImageResourceFromFile 等)
绝对位置布局WatermarkSettingsx_posy_pos(毫米)、widthheightrotation(0–360°)、opacity(0–255)
对齐布局AlignmentWatermarkSettingsh_alignv_align(左/中/右,上/中/下)及尺寸、旋转、透明度
平铺布局TiledWatermarkSettings继承 WatermarkSettingsx_stepy_step(毫米,须 > 0)
区域范围foxit::RectFleftbottomrighttop(OFD 坐标系)
文本水印AddTextWatermarkAddAlignTextWatermark
AddTiledTextWatermarkAddRegionTextWatermark
AddMultiAreaTextWatermark
按布局方式添加文字水印
图片水印AddImageWatermarkAddAlignImageWatermark
AddTiledImageWatermarkAddRegionImageWatermark
AddMultiAreaImageWatermark
按布局方式添加图片水印
持久化OFDPackage::SaveSaveAs水印写入页面后须保存文件包

添加文本水印

定义 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);
    }
}

平铺水印

TiledWatermarkSettingsWatermarkSettings 基础上增加 x_stepy_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::SaveSaveAs 写回文件。预览带水印效果可结合 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,多页文档须逐页创建并添加;无文档级一次性全局接口。
  • 图片资源 IDImagePropertiesimage_id 须为 OFDDoc::AddImageResourceFromFile 等返回的有效 ID(非 0);详见 元数据、资源与自定义数据
  • 单位与范围:位置与尺寸单位为毫米rotation 为 0–360(不含 360);opacity 为 0–255;平铺 x_step / y_step 须大于 0。
  • 坐标系WatermarkSettingsx_pos / y_posRectF 区域使用 OFD 坐标系,添加前请确认原点与轴向,避免位置偏差。
  • 区域平铺AddRegion*Watermark 的平铺仅在指定 RectF 内生效,超出区域部分不绘制。
  • 性能与体积:步长过小的平铺水印会显著增加图元数量,可能导致文件体积增大或渲染变慢,请按实际需求调整密度。