首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PDFClown复制注释,然后操作它们

PDFClown复制注释,然后操作它们
EN

Stack Overflow用户
提问于 2018-04-29 19:06:09
回答 2查看 345关注 0票数 0

我需要将注释从一个PDF文件复制到另一个PDF文件。我使用了优秀的PDFClown库,但无法操纵颜色、旋转等东西。这有可能吗?我可以看到基本对象的信息,但也不确定如何直接操作。

我可以复制外观通过克隆外观,但不能“编辑”它。

提前谢谢。亚历克斯

如果作者是斯蒂芬诺,那么项目是否已经死了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-14 14:22:46

一般注解,特别是标注注解

我研究了一下,恐怕没有什么可以用高级方法对任意输入进行决定性的操作。原因是有许多其他方法来设置标注注释的外观,而PDF只支持使用显式高级别方法的优先级较低的方法。从高度优先向下

  • AP流中的显式显示。如果给出了它,就会使用它,忽略这个外观看起来是否一点都像标注注释,更不用说像由其他Callout属性定义的一个了。 PDF还没有为其他值的标注注释创建外观,更不用说更新现有外观来跟踪某些特定属性(例如Color)的变化。对于ISO 32000-2的支持,这里的PDF必须改进,因为外观流已经成为强制性的. 如果它存在,您可以使用getAppearance()检索外观,但是您只能得到一个带有低级别绘图指令的FormXObject,没有任何特定的标注。 在给定FormXObject的情况下,您可以很容易地操作一件事情,通过相应地设置它的矩阵,您可以很容易地旋转或倾斜外观。 annotation.getAppearance().getNormal().get(null).setMatrix(AffineTransform.getRotateInstance(100,10);
  • RC字符串或流中的富文本字符串。除非出现了外观,否则标注文本框中的文本将从这个富文本数据中生成(此处的富文本使用XHTML1.0子集进行格式化)。 PDF尚未为标注文本创建丰富的文本表示,更不用说更新现有文本以跟踪某些特定属性(例如Color)的更改。 如果存在,您可以使用getBaseDataObject().get(PdfName.RC)通过低级别访问检索富文本,更改此字符串或流,并使用getBaseDataObject().put(PdfName.RC, ...)再次设置它。类似地,您可以使用名称PdfName.DS检索、操作和设置富文本默认样式字符串。
  • 用于在没有外观流和(就文本内容而言)丰富文本字符串的情况下构建标注的独立方面的许多不同设置。 PDF支持(许多)这些属性,特别是如果将克隆的注释转换为StaticNote,例如使用get/set/withAlpha的不透明度CA、使用get/set/withBorder的边界边框/ BS、背景色E 129C<代码>E 230使用get/set/withColor、. 顺便说一下,它的行尾样式LE支持有一个错误:显然, line 注释LE属性的代码是未经检查就复制的;不幸的是,该属性遵循了不同的语法.

你的任务

因此,关于您声明要更改的属性,

  • 旋转:标注注释本身中没有旋转属性(除了标志之外,是否遵循页面旋转)。因此,不能将旋转设置为简单的注释属性。但是,如果源注释确实有一个外观流,则可以操作它的矩阵,使其在注释矩形内旋转,请参见上面的内容。
  • 边框颜色和字体:如果您的标注有外观流,您可以尝试使用ContentScanner解析其内容,并操作颜色和字体设置操作。否则,如果设置了富文本信息,则可以尝试使用一些XML解析器和操作字体样式属性来解析富文本。否则,您可以解析默认外观DA字符串并操作其字体和颜色设置说明。

一些示例代码

我使用Acrobat:Callout-Yellow.pdf创建了一个带有示例标注的文件。它包含一个外观流、丰富的文本和简单的属性,因此我们可以在不同的级别上使用这个文件,例如操作。

我为keepAppearanceStreamkeepRichText应用了这段代码的不同值(您没有提到您是使用PDF还是.Net;所以我选择了Java;但是,到.Net的端口应该是微不足道的……):

代码语言:javascript
复制
boolean keepAppearanceStream = ...;
boolean keepRichText = ...;

try (   InputStream sourceResource = GET_STREAM_FOR("Callout-Yellow.pdf");
        InputStream targetResource = GET_STREAM_FOR("test123.pdf");
        org.pdfclown.files.File sourceFile = new org.pdfclown.files.File(sourceResource);
        org.pdfclown.files.File targetFile = new org.pdfclown.files.File(targetResource); ) {
    Document sourceDoc = sourceFile.getDocument();
    Page sourcePage = sourceDoc.getPages().get(0);
    Annotation<?> sourceAnnotation = sourcePage.getAnnotations().get(0);

    Document targetDoc = targetFile.getDocument();
    Page targetPage = targetDoc.getPages().get(0);

    StaticNote targetAnnotation = (StaticNote) sourceAnnotation.clone(targetDoc);

    if (keepAppearanceStream) {
        // changing properties of an appearance
        // rotating the appearance in the appearance rectangle
        targetAnnotation.getAppearance().getNormal().get(null).setMatrix(AffineTransform.getRotateInstance(100, 10));
    } else {
        // removing the appearance to allow lower level properties changes
        targetAnnotation.setAppearance(null);
    }

    // changing text background color
    targetAnnotation.setColor(new DeviceRGBColor(0, 0, 1));

    if (keepRichText) {
        // changing rich text properties
        PdfString richText = (PdfString) targetAnnotation.getBaseDataObject().get(PdfName.RC);
        String richTextString = richText.getStringValue();
        // replacing the font family
        richTextString = richTextString.replaceAll("font-family:Helvetica", "font-family:Courier");
        richText = new PdfString(richTextString);
        targetAnnotation.getBaseDataObject().put(PdfName.RC, richText);
    } else {
        targetAnnotation.getBaseDataObject().remove(PdfName.RC);
        targetAnnotation.getBaseDataObject().remove(PdfName.DS);
    }

    // changing default appearance properties
    PdfString defaultAppearance = (PdfString) targetAnnotation.getBaseDataObject().get(PdfName.DA);
    String defaultAppearanceString = defaultAppearance.getStringValue();
    // replacing the font
    defaultAppearanceString = defaultAppearanceString.replaceFirst("Helv", "HeBo");
    // replacing the text and line color
    defaultAppearanceString = defaultAppearanceString.replaceFirst(". . . rg", ".5 g");
    defaultAppearance = new PdfString(defaultAppearanceString);
    targetAnnotation.getBaseDataObject().put(PdfName.DA, defaultAppearance);

    // changing the text value
    PdfString contents = (PdfString) targetAnnotation.getBaseDataObject().get(PdfName.Contents);
    String contentsString = contents.getStringValue();
    contentsString = contentsString.replaceFirst("text", "text line");
    contents = new PdfString(contentsString);
    targetAnnotation.getBaseDataObject().put(PdfName.Contents, contents);

    // change the line width and style
    targetAnnotation.setBorder(new Border(0, new LineDash(new double[] {3, 2})));

    targetPage.getAnnotations().add(targetAnnotation);

    targetFile.save(new File(RESULT_FOLDER, "test123-withCalloutCopy.pdf"),  SerializationModeEnum.Standard);
}

(https://github.com/mkl-public/testarea-pdfclown0/blob/master/src/test/java/mkl/testarea/pdfclown0/annotate/CopyCallOut.java#L44 test testCopyCallout__)

请注意,代码只具有概念质量的证明:对于任意的PDF,您不能简单地期望将“字体-家族:Helvetica”的字符串替换为“字体-家族:信使”,或将"HeBo“或".5 g”替换为“.5……rg”:字体可以使用不同的样式属性或名称,并且可以使用不同的着色指令。

Adobe中的屏幕快照

  • 原始档案:

  • keepAppearanceStream = true

  • keepAppearanceStream = falsekeepRichText = true

  • keepAppearanceStream = falsekeepRichText = false

票数 0
EN

Stack Overflow用户

发布于 2018-05-15 10:41:20

作为一篇文章的评论,Mkl在创建新的注释时,您的好建议确实很有帮助。我确实应用了以下方法来“复制”现有注释,其中注释是“克隆”注释和源baseAnnotation注释

代码语言:javascript
复制
 foreach (PdfName t in baseAnnotation.BaseDataObject.Keys)
  {
                if (t.Equals(PdfName.DA) || t.Equals(PdfName.DS) || t.Equals(PdfName.RC) || t.Equals(PdfName.Rotate))
                {
                    note.BaseDataObject[t] = baseAnnotation.BaseDataObject[t];
                }
            }

再次感谢

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50090277

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档