Skip to content

OFD 渲染

本节介绍如何使用 OFDRender 将 OFD 页面渲染到位图。OFDRender 位于 foxit::common 命名空间,面向 OFDPage 对象;若需不区分 PDF/OFD 的统一渲染,请参阅 FLD 渲染

任务场景

  • 预览 OFD 页面或导出为 PNG 等图片。
  • 配置颜色模式、前景/背景色、DPI 等渲染参数。
  • 控制是否渲染注释等页面内容(OFDRender 内容标志)。

API 概览

功能C++ API(foxit::common / foxit::ofd核心参数 / 描述
页面渲染OFDRender构造绑定 BitmapStartRender(OFDPage, matrix) 返回 Progressive
渲染选项OFDRenderOptioncolor_modeback_colorfore_colorx_dpi / y_dpirender_flags
内容标志OFDRender::ContentFlage_RenderPage、注释/签章层等(SetRenderOption 传入)
显示矩阵OFDPage::GetDisplayMatrixlefttopwidthheightRotation
页面区域OFDPage::GetPageBoxPageBoxType(如 e_PhysicalBox)用于计算位图尺寸
目标位图Bitmap渲染前创建并填充背景色

基本渲染流程

从文件渲染 OFD 页面时,需先经 OFD 文件包 打开并加载文档,取得 OFDPage 后再调用 OFDRender。打开链路说明请参阅 OFD 功能概述

取得 OFDPage 后的渲染步骤如下:

  1. 通过 GetPageBox 读取页面区域,按目标 DPI 计算位图宽高。
  2. 创建 Bitmap 并填充背景色。
  3. 调用 GetDisplayMatrix 计算显示矩阵。
  4. 构造 OFDRender,调用 StartRender 开始渲染。
  5. 循环推进 Progressive(C++ 为 Continue,Java 为 resume),直至返回 e_Finished 且进度为 100%;若返回 e_Error 或进度为 -1,表示渲染失败。

示例

以下示例演示将第一页渲染为位图。

c++
#include "common/fs_render.h"
#include "ofd/fs_ofdpackage.h"
#include "ofd/fs_ofddoc.h"
#include "ofd/fs_ofdpage.h"

using namespace foxit;
using namespace foxit::common;
using namespace foxit::ofd;

bool RenderFirstOFDPage(const wchar_t* input_file) {
  OFDPackage package(input_file);
  if (package.IsEmpty()) {
    return false;
  }

  OFDDoc doc = package.LoadDocument(0, "");
  if (doc.IsEmpty() || doc.GetPageCount() <= 0) {
    return false;
  }

  OFDPage page = doc.GetPage(0);
  if (page.IsEmpty()) {
    return false;
  }

  RectF page_box = page.GetPageBox(OFDPage::e_PhysicalBox);
  float page_width = page_box.right - page_box.left;
  float page_height = page_box.bottom - page_box.top;
  int render_width = (int)(page_width * 96 / 72);
  int render_height = (int)(page_height * 96 / 72);

  Bitmap bitmap(render_width, render_height, Bitmap::e_DIBArgb);
  bitmap.FillRect(0xFFFFFFFF, NULL);

  Matrix matrix = page.GetDisplayMatrix(0, 0, render_width, render_height, e_Rotation0);

  OFDRender render(bitmap);
  Progressive progressive = render.StartRender(page, matrix, NULL);
  int progress = progressive.GetRateOfProgress();
  if (progress < 0) {
    return false;
  }

  Progressive::State state =
      progress == 100 ? Progressive::e_Finished : Progressive::e_ToBeContinued;
  while (state == Progressive::e_ToBeContinued) {
    state = progressive.Continue();
  }
  return state == Progressive::e_Finished && progressive.GetRateOfProgress() == 100;
}
java
import com.foxit.sdk.common.Bitmap;
import com.foxit.sdk.common.OFDRender;
import com.foxit.sdk.common.Progressive;
import com.foxit.sdk.common.fxcrt.Matrix2D;
import com.foxit.sdk.common.fxcrt.RectF;
import com.foxit.sdk.ofd.OFDDoc;
import com.foxit.sdk.ofd.OFDPackage;
import com.foxit.sdk.ofd.OFDPage;

import static com.foxit.sdk.common.Constants.e_Rotation0;

public class OFDRenderBasic {
    public static boolean renderFirstOFDPage(String inputFile) throws Exception {
        OFDPackage pkg = new OFDPackage(inputFile);
        if (pkg.isEmpty()) {
            return false;
        }

        OFDDoc doc = pkg.loadDocument(0, null);
        if (doc.isEmpty() || doc.getPageCount() <= 0) {
            return false;
        }

        OFDPage page = doc.getPage(0);
        if (page.isEmpty()) {
            return false;
        }

        RectF pageBox = page.getPageBox(OFDPage.e_PhysicalBox);
        float pageWidth = pageBox.getRight() - pageBox.getLeft();
        float pageHeight = pageBox.getBottom() - pageBox.getTop();
        int renderWidth = (int) (pageWidth * 96 / 72);
        int renderHeight = (int) (pageHeight * 96 / 72);

        Bitmap bitmap = new Bitmap(renderWidth, renderHeight, Bitmap.e_DIBArgb, null, 0);
        bitmap.fillRect(0xFFFFFFFFL, null);

        Matrix2D matrix = page.getDisplayMatrix(0, 0, renderWidth, renderHeight, e_Rotation0);

        OFDRender render = new OFDRender(bitmap);
        Progressive progressive = render.startRender(page, matrix, null);
        int progress = progressive.getRateOfProgress();
        if (progress < 0) {
            return false;
        }

        int state = progress == 100 ? Progressive.e_Finished : Progressive.e_ToBeContinued;
        while (state == Progressive.e_ToBeContinued) {
            state = progressive.resume();
        }
        return state == Progressive.e_Finished && progressive.getRateOfProgress() == 100;
    }
}

注意事项

  • OFDRender::StartRender 返回 Progressive,需调用 Continue(C++)或 resume(Java)推进渲染;循环中应检查返回状态,仅在 e_Finished 且进度为 100% 时表示成功,e_Error 或进度 -1 表示失败。
  • FLDRender 面向 FLDPage 且为同步 Render 返回布尔值,与 OFDRender 的渐进式模型不同。
  • 创建 OFDRender 时传入的 Bitmap 须在渲染完成前保持有效。