【问题标题】:Java-PDFbox: Creating the artifact tag for lines and underlines in tagged PDFJava-PDFbox:为标记的 PDF 中的线条和下划线创建工件标记
【发布时间】:2021-08-26 06:22:56
【问题描述】:

我正在从标记的 pdf 创建可访问性 PDF。它显示“路径对象未标记”错误。 PDF 有线条和带下划线的文本。因此,我正在尝试为未标记的订单项添加“ARTIFACT”标签。我可以从PDFGraphicsStreamEngine 获得线路。谁能帮我解决这个问题?

PDF Page PAC3 Error

【问题讨论】:

标签: java pdf pdfbox tagged-pdf


【解决方案1】:

您可以使用来自this answerPdfContentStreamEditor 类来根据需要通过自定义和调用它来编辑页面内容流:

PDDocument document = ...;
for (PDPage page : document.getDocumentCatalog().getPages()) {
    PdfContentStreamEditor markEditor = new PdfContentStreamEditor(document, page) {
        int markedContentDepth = 0;

        @Override
        public void beginMarkedContentSequence(COSName tag, COSDictionary properties) {
            if (inArtifact) {
                System.err.println("Structural error in content stream: Path not properly closed by path painting instruction.");
            }
            markedContentDepth++;
            super.beginMarkedContentSequence(tag, properties);
        }

        @Override
        public void endMarkedContentSequence() {
            markedContentDepth--;
            super.endMarkedContentSequence();
        }

        boolean inArtifact = false;

        @Override
        protected void write(ContentStreamWriter contentStreamWriter, Operator operator, List<COSBase> operands) throws IOException {
            String operatorString = operator.getName();

            boolean unmarked = markedContentDepth == 0;
            boolean inArtifactBefore = inArtifact;

            if (unmarked && (!inArtifactBefore) && PATH_CONSTRUCTION.contains(operatorString)) {
                super.write(contentStreamWriter, Operator.getOperator("BMC"), Collections.singletonList(COSName.ARTIFACT));
                inArtifact = true;
            }

            super.write(contentStreamWriter, operator, operands);

            if (unmarked && inArtifactBefore && PATH_PAINTING.contains(operatorString)) {
                super.write(contentStreamWriter, Operator.getOperator("EMC"), Collections.emptyList());
                inArtifact = false;
            }
        }

        final List<String> PATH_CONSTRUCTION = Arrays.asList("m", "l", "c", "v", "y", "h", "re");
        final List<String> PATH_PAINTING = Arrays.asList("s", "S", "f", "F", "f*", "B", "B*", "b", "b*", "n");
    };
    markEditor.processPage(page);
}
document.save(...);

(EditMarkedContent 测试testMarkUnmarkedPathsAsArtifactsTradeSimple1)

beginMarkedContentSequenceendMarkedContentSequence 覆盖跟踪当前标记的内容嵌套深度,特别是当前内容是否被标记。

对于尚未标记的指令,write 覆盖然后将未标记的路径构造和绘制指令序列包含在 /Artifact BMC ... EMC 中。

请注意,此代码仅考虑页面内容流中的内容,它不会下降到 XObjects、Pattern 等表单中。

此外,如果内容流有错误(例如,没有绘画的路径构造),此​​代码可能会添加额外的错误(例如,不平衡的标记内容开始和结束)。

【讨论】:

  • 它在“Collections.singletonList(COSName.ARTIFACT)”和“Collections.emptyList()”中显示错误。 PdfContentStreamEditor 具有带有“List”参数的“写入”功能。
  • 这里没有。我会添加一个完整源代码的链接,也许你导入了一个不同的Collections 类。这是EditMarkedContent.java
  • 仍然显示错误 - PdfContentStreamEditor 类型中的方法 write(ContentStreamWriter, Operator, List) 不适用于参数 (ContentStreamWriter, Operator, List)
  • 您使用哪个 java 版本?您的版本似乎没有灵活的泛型解析。您可以分别尝试使用Collections.&lt;COSBase&gt;singletonList(COSName.ARTIFACT)Collections.&lt;COSBase&gt;emptyList()
  • 现在工作正常。正如您所说,正在使用上述行。我正在使用 java 11.0.11。非常感谢。我可以知道您使用的是哪个版本并且可以正常工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-23
  • 1970-01-01
  • 1970-01-01
  • 2021-02-14
  • 2016-09-15
  • 1970-01-01
相关资源
最近更新 更多