Skip to content

PDF 渲染 (Render)

PDF 渲染是通过福昕渲染引擎实现的,福昕渲染引擎是一个图形引擎,用于将页面渲染到位图或平台设备上下文。福昕 PDF SDK 提供了 APIs 用来设置渲染选项 /flags,例如设置 flag 来决定是否渲染表单域和签名,是否绘制图像反锯齿 (anti-aliasing) 和路径反锯齿。可以使用以下 APIs 进行渲染:

  • 渲染页面和注释时,首先使用 Renderer.SetRenderContentFlags 接口来决定是否同时渲染页面和注释,然后使用Renderer.StartRender 接口进行渲染。Renderer.StartQuickRender 接口也可以用来渲染页面,但仅用于缩略图。
  • 渲染单个 annotation 注释,使用 Renderer.RenderAnnot 接口。
  • 在位图上渲染,使用 Renderer.StartRenderBitmap 接口。
  • 渲染一个重排的页面,使用 Renderer.StartRenderReflowPage 接口。

在福昕 PDF SDK 中,Widget 注释常与表单域和表单控件相关联。渲染 widget 注释,推荐使用如下的流程:

  • 加载 PDF 页面后,首先渲染页面以及该页面上所有的注释 (包括 widget 注释)。
  • 如果使用 FoxitRDKNative.pdf.interform.Filler 对象来填表,则应使用 FoxitRDKNative.pdf.interform.Filler.Render 接口来渲染当前获取到焦点的表单控件,而不是使用 Renderer.RenderAnnot 接口。

如何将指定的 PDF 页面渲染到 bitmap

js
import { image } from '@kit.ImageKit';
import { FoxitRDKNative } from 'foxit_rdk';
import { BusinessError } from '@ohos.base';

class RenderUnit {
  public pixelMap?: image.PixelMap;

  public renderPage(page: FoxitRDKNative.pdf.PDFPage, width: number, height: number): void {

    try {
      if (!page.IsParsed()) {
        class PauseCallBackImpl extends FoxitRDKNative.common.PauseCallback {
          NeedToPauseNow(): boolean {
            return false;
          }
        }

        const progressive = page.StartParse(FoxitRDKNative.pdf.PDFPage.e_ParsePageNormal, new PauseCallBackImpl(), false)
        let state = FoxitRDKNative.common.Progressive.e_ToBeContinued;
        while (state == FoxitRDKNative.common.Progressive.e_ToBeContinued) {
          state = progressive.Continue();
        }
      }

      const w: number = Math.ceil(width);
      const h: number = Math.ceil(height);
      const size: number = w * h * 4;

      const matrix: FoxitRDKNative.common.fxcrt.Matrix2D = page.GetDisplayMatrix(0, 0, w, h, FoxitRDKNative.common.e_Rotation0)
      const color: ArrayBuffer = new ArrayBuffer(size)
      const bitmap: FoxitRDKNative.common.Bitmap =
        new FoxitRDKNative.common.Bitmap(w, h, FoxitRDKNative.common.Bitmap.e_DIBArgb, color, w * 4)
      bitmap.FillRect(0xFFFFFFFF)
      const render: FoxitRDKNative.common.Renderer = new FoxitRDKNative.common.Renderer(bitmap, false);

      class PauseCallBackImpl extends FoxitRDKNative.common.PauseCallback {
        NeedToPauseNow(): boolean {
          return false;
        }
      }

      const progressive = render.StartRender(page, matrix, new PauseCallBackImpl());
      let state = FoxitRDKNative.common.Progressive.e_ToBeContinued;
      while (state == FoxitRDKNative.common.Progressive.e_ToBeContinued) {
        state = progressive.Continue();
      }
      let opts: image.InitializationOptions =
        { editable: false, pixelFormat: image.PixelMapFormat.RGBA_8888, size: { height: h, width: w } }
      image.createPixelMap(color, opts, (error: BusinessError, pixelMap: image.PixelMap) => {
        if (error) {
          console.error('Failed to create pixelMap.');
          return;
        }

        this.pixelMap = pixelMap; // 使用 Image 或者其他组件将 pixelMap 加载到布局上面
        console.log('Succeeded in creating pixelMap.');
      })
    } catch (e) {
      console.error(e);
    }
  }
}