Skip to content
ComPDF
Guides

创建注释

ComPDF 支持多种类型的注释,包括文本注释、链接、图形、高亮、图章、手写标注以及音频注释,全面满足不同的注释需求。

ComPDF Flutter SDK 提供两种方式创建注释:

  1. 通过 CPDFReaderWidget 组件的注释模式创建注释(推荐)。
  2. 通过 CPDFDocument API 编程方式创建注释。

交互创建注释

通过 CPDFReaderWidget,用户可以进入注释模式,从底部工具栏中选择注释类型,并通过触摸操作添加注释。也可以通过 controller.setAnnotationMode(CPDFAnnotationType type) 方法以编程方式设置注释类型。

dart
CPDFReaderWidgetController? _controller;

// Initialize CPDFReaderWidget and get the controller in the onCreated callback
CPDFReaderWidget(
  document: widget.documentPath,
  password: widget.password,
  configuration: widget.configuration,
  onCreated: (controller) {
    setState(() {
      _controller = controller;
    });
  },
);

await _controller?.setAnnotationMode(CPDFAnnotationType.highlight);

完整支持的注释类型(CPDFAnnotationType 枚举)包括:

注释类型枚举值
文本注释note
高亮highlight
下划线underline
波浪线squiggly
删除线strikeout
墨水ink
铅笔pencil
圆形circle
矩形square
箭头arrow
线段line
文本freetext
电子签名signature
图章注释stamp
图片pictures
链接link
音频sound
退出绘制模式unknown

编程创建注释

ComPDF 还支持通过 CPDFDocument API 编程方式创建注释, 以下示例展示了如何在指定页面上创建各种类型注释:

要注意的是,rect 参数定义了注释在页面上的位置和大小,坐标系的原点位于页面的左下角。

  • 创建便签注释

dart
final annotations = [
  CPDFNoteAnnotation(
    page: 0,
    createDate: DateTime.now(),
    title: 'ComPDF-Flutter',
    content: 'This is Note Annotation',
    rect: const CPDFRectF(left: 260, top: 740, right: 300, bottom: 700),
    color: Colors.green,
    alpha: 255)
];
await controller.document.addAnnotations(annotations);
  • 创建标记注释

标记注释包含高亮下划线波浪线删除线四种类型。

dart
final annotations = [
  CPDFMarkupAnnotation(
    type: CPDFAnnotationType.highlight,
    page: 1,
    createDate: DateTime.now(),
    title: 'ComPDF-Flutter',
    content: 'This is Highlight Annotation',
    rect: const CPDFRectF(left: 55, top: 800, right: 180, bottom: 770),
    markedText: 'Annotations',
    color: Colors.green,
    alpha: 200),
];
await controller.document.addAnnotations(annotations);
  • 创建墨水注释(Ink)

Ink注释不需要指定rect参数,通过inkPath确定绘制的路径确定位置。

dart
final annotations = [
  CPDFInkAnnotation(
    page: 0,
    color: Colors.deepOrangeAccent,
    borderWidth: 10,
    inkPath: [
      [
        [176.43, 72.22],
        [206.94, 78.95],
        [217.57, 82.21],
        [227.0, 85.49],
        [232.42, 87.92],
        [243.73, 91.83],
        [254.87, 97.98],
        [269.0, 104.22],
        [281.4, 110.47],
        // ... more points
      ]
    ],
  )
];
await controller.document.addAnnotations(annotations);
  • 创建图形注释

形状注释包括正方形、圆形、线条和箭头类型。

dart
final annotations = [
  CPDFSquareAnnotation( // 矩形注释示例
    page: 0,
    title: 'Square',
    content: 'This is a square annotation with long content. ',
    createDate: DateTime.now(),
    rect: const CPDFRectF(left: 20, top: 200, right: 200, bottom: 100),
    borderWidth: 5,
    borderColor: Colors.deepOrangeAccent,
    fillColor: Colors.lightGreenAccent,
    effectType: CPDFBorderEffectType.solid,
    borderAlpha: 255,
    dashGap: 0,
    fillAlpha: 100),
  CPDFCircleAnnotation( // 圆形注释示例
    page: 0,
    title: 'Circle-A',
    content: 'This is a circle annotation.',
    createDate: DateTime.now(),
    rect: const CPDFRectF(left: 220, top: 200, right: 360, bottom: 100),
    borderWidth: 5,
    borderColor: Colors.blueAccent,
    fillColor: Colors.yellowAccent,
    effectType: CPDFBorderEffectType.solid,
    borderAlpha: 255,
    fillAlpha: 120,
    dashGap: 0),
  CPDFLineAnnotation( // 线段注释示例, 线段类型注释无需设置rect参数,通过points确定位置
    type: CPDFAnnotationType.line,
    title: 'Line-A',
    page: 1,
    createDate: DateTime.now(),
    content: 'This is a line annotation.',
    borderWidth: 6,
    borderColor: Colors.purple,
    borderAlpha: 255,
    fillColor: Colors.transparent,
    fillAlpha: 255,
    points: [
      [504, 219],   // 起点坐标
      [320, 88],    // 终点坐标
    ]),
  CPDFLineAnnotation( // 箭头注释示例, 箭头类型注释无需设置rect参数,通过points确定位置
    type: CPDFAnnotationType.arrow,
    title: 'Arrow-A',
    page: 1,
    createDate: DateTime.now(),
    content: 'This is an arrow annotation.',
    points: [
      [288, 342],   // 起点坐标
      [159, 209]    // 终点坐标
    ],
    borderWidth: 6,
    borderColor: Colors.teal,
    borderAlpha: 255,
    fillColor: Colors.transparent,
    fillAlpha: 255,
    lineHeadType: CPDFLineType.square,
    lineTailType: CPDFLineType.openArrow,
    dashGap: 0)
];
await controller.document.addAnnotations(annotations);
  • 创建文本注释

dart
final annotations = [
  CPDFFreeTextAnnotation(
    title: 'Freetext',
    page: 0,
    createDate: DateTime.now(),          
    content: 'Hello, ComPDF!',
    rect: const CPDFRectF(left: 30, top: 750, right: 230, bottom: 700),
    textAttribute: CPDFTextAttribute(
      color: Colors.black,
      familyName: 'Times',
      styleName: 'Bold',
      fontSize: 20,
    ),
    alpha: 255,
    alignment: CPDFAlignment.left)
];
await controller.document.addAnnotations(annotations);

familyName 和 styleName 可选,若不指定则使用系统默认字体。可使用ComPDFKit.getFonts() 方法获取系统支持的字体列表。

  • 创建图章注释

dart
final annotations = [
  CPDFStampAnnotation(  // 标准图章注释示例
    page: 0,
    title: 'Stamp-A',
    createDate: DateTime.now(),
    content: 'Approved',
    rect: const CPDFRectF(left: 20, top: 300, right: 200, bottom: 260),
    stampType: CPDFStampType.standard,
    standardStamp: CPDFStandardStamp.accepted),

  CPDFStampAnnotation(  // 自定义文字图章注释示例
    page: 0,
    title: 'Stamp-A',
    createDate: DateTime.now(),
    content: 'Custom Text Stamp',
    rect: const CPDFRectF(left: 220, top: 300, right: 350, bottom: 260),
    stampType: CPDFStampType.text,
    textStamp: CPDFTextStamp(
      content: 'Test Text',
      date: CPDFDate.getTextStampDate(timeSwitch: false, dateSwitch: true),
      shape: CPDFTextStampShape.leftTriangle,
      color: CPDFTextStampColor.red))
];
await controller.document.addAnnotations(annotations);
  • 创建图片注释

dart
final annotations = [
  CPDFImageAnnotation(
    page: 0,
    createDate: DateTime.now(),
    title: 'Stamp-Image',
    content: 'Custom Image Stamp',
    rect: const CPDFRectF(left: 380, top: 420, right: 550, bottom: 260),
    image: 'iVBORw0KGgoAAAANSUhEUgAAAgIAAABzCAY...') // 图片数据,支持Base64编码字符串,
];
await controller.document.addAnnotations(annotations);
  • 创建签名注释

dart
final annotations = [
  CPDFSignatureAnnotation(
    page: 1,
    createDate: DateTime.now(),
    title: 'Stamp-Image',
    content: 'Signature',
    rect: const CPDFRectF(left: 380, top: 420, right: 550, bottom: 260),
    image: 'iVBORw0KGgoAAAANSUhEUgAAAg...') // 图片数据,支持Base64编码字符串,
];
await controller.document.addAnnotations(annotations);
  • 创建链接注释

dart
final annotations = [
  CPDFLinkAnnotation(  // 链接到网页
    title: 'ComPDF-Flutter',
    page: 0,
    createDate: DateTime.now(),
    content: 'Link Annotation',
    rect: const CPDFRectF(left: 248, top: 799, right: 407, bottom: 732),
    action: CPDFUriAction(uri: 'https://www.compdf.com')),

  CPDFLinkAnnotation(  // 跳转到指定页码
    title: 'ComPDF-Flutter',
    page: 0,
    createDate: DateTime.now(),
    content: 'Link Annotation',
    rect: const CPDFRectF(left: 374, top: 304, right: 530, bottom: 236),
    action: CPDFGoToAction(pageIndex: 2)),

  CPDFLinkAnnotation(  // 发送邮件
    title: 'ComPDF-Flutter',
    page: 0,
    content: 'Link Annotation',
    createDate: DateTime.now(),
    rect: const CPDFRectF(left: 374, top: 199, right: 529, bottom: 121),
    action: CPDFUriAction.email(email: '[email protected]')),
];

await controller.document.addAnnotations(annotations);
  • 创建音频注释

dart
final annotations = [
  CPDFSoundAnnotation(
    title: 'ComPDF-Flutter',
    page: 0,
    content: 'Link Annotation',
    rect: const CPDFRectF(left: 75, top: 607, right: 119, bottom: 563),
    soundPath: soundPath.path), // 音频文件路径
];
await controller.document.addAnnotations(annotations);

退出注释创建模式

完成注释后,可调用以下方法退出注释状态:

dart
await _controller?.setAnnotationMode(CPDFAnnotationType.unknown);

获取当前绘制注释类型

可用于判断当前是否处于注释状态或获取当前选中的注释工具:

dart
CPDFAnnotationType currentType = await _controller?.getAnnotationMode();