Java 使用PDFBox标记PDF

Java 使用PDFBox标记PDF,java,accessibility,pdfbox,tagged-pdf,Java,Accessibility,Pdfbox,Tagged Pdf,是否可以使用PDFBox创建带标签的PDF(PDF/UA)?看起来PDFBox有一个API(packageorg.apache.PDFBox.pdmodel.documentinterchange.taggedpdf),但我找不到任何教程或代码示例 使用下面的代码,我生成了一个包含图像的PDF文件,屏幕阅读器NVDA(在我的例子中)识别它并读取“。。。图形替代说明'。但是,辅助功能检查器显示错误:“未标记图像对象” PDDocument doc = new PDDocument(

是否可以使用PDFBox创建带标签的PDF(PDF/UA)?看起来PDFBox有一个API(package
org.apache.PDFBox.pdmodel.documentinterchange.taggedpdf
),但我找不到任何教程或代码示例

使用下面的代码,我生成了一个包含图像的PDF文件,屏幕阅读器NVDA(在我的例子中)识别它并读取“。。。图形替代说明'。但是,辅助功能检查器显示错误:“未标记图像对象”

        PDDocument doc = new PDDocument();
        PDPage page = new PDPage();
        doc.addPage(page);
        PDDocumentCatalog documentCatalog = doc.getDocumentCatalog();

        PDImageXObject pdImage = PDImageXObject.createFromFile(imagePath, doc);
        PDPageContentStream contents = new PDPageContentStream(doc, page);
        contents.drawImage(pdImage, 100, 600, pdImage.getWidth() / 2, pdImage.getHeight() / 2);
        contents.close();

        PDStructureTreeRoot treeRoot = new PDStructureTreeRoot();
        PDStructureElement structureElement = new PDStructureElement(StandardStructureTypes.Figure, treeRoot);
        structureElement.setPage(page);

        PDMarkedContent markedImg = new PDMarkedContent(COSName.IMAGE, new COSDictionary());
        markedImg.addXObject(pdImage);

        structureElement.appendKid(markedImg);
        structureElement.setAlternateDescription("Alternate Description");
        treeRoot.appendKid(structureElement);
        documentCatalog.setStructureTreeRoot(treeRoot);
        // ....
        doc.save(fileName);

你能提供一些关于这个主题的解释或代码示例吗

我举了一个工作示例,演示如何使用PDFBox 2创建可访问的PDF:

问题代码中缺少一些东西。标记的内容需要alt文本,我相信您需要标记内容的mcid

示例项目更详细地演示了您需要什么

应该是这样的:

PDPageContentStream contents = new PDPageContentStream(doc, page);

// the content in the stream needs an id
int mcid = 5;
COSDictionary dictionary = new COSDictionary();
dictionary = new COSDictionary();
dictionary(COSName.MCID, mcid);

// wrap image drawing in marked content
contents.beginMarkedContent(COSName.IMAGE, PDPropertyList.create(dictionary));
contents.drawImage(pdImage, 100, 600, pdImage.getWidth() / 2, pdImage.getHeight() / 2);
contents.endMarkedContent();

contents.close();

PDStructureTreeRoot treeRoot = new PDStructureTreeRoot();
documentCatalog.setStructureTreeRoot(treeRoot);
PDStructureElement structureElement = new PDStructureElement(StandardStructureTypes.Figure, treeRoot);
structureElement.setPage(page);
structureElement.setAlternateDescription("Alternate Description");

// Set alt text on marked content for structure.  
// This is the dictionary with the mcid used in beginMarkedContent.
dictionary.setString(COSName.ALT, "Alternate Description");
PDMarkedContent markedImg = new PDMarkedContent(COSName.IMAGE, dictionary);
markedImg.addXObject(pdImage);
structureElement.appendKid(markedImg);

遗憾的是,没有任何例子,主要是因为我们都没有参与创建这样的文件,阿法克。(我是PDFBox提交者)我能为您做的唯一一件事就是修复您可能发现的任何bug。您可以使用其他工具创建一个文件,然后使用PDFBox PDFDebugger查看结构并复制它。@tilmahausher,谢谢PDFDebugger。现在的主要问题是如何直接在
PDPageContentStream
中编写
pdstructurelement
。我想您指的是BMC、BDC、EMC、MP、DP。此时,您需要使用(不推荐使用的)“raw”方法。或者在JIRA中为一些新方法创建请求:-)PDFBox 1.8可以创建PDF/a,但不能创建PDF/a-1a,后者也包括PDF/UA。我还不能确定PDFBOX2.0是否支持PDF/A-1a。如果使用PDFBox 2生成的PDF/a文档没有可访问性标记,我假设它还不受支持?@leomuz,你有acrobat吗?您可以在acrobat中运行辅助功能检查器,查看它是否与pac2有相同的错误。您还可以查看标记树(视图>显示/隐藏>导航窗格>标记)。如果您没有acrobat,可以脱机与我联系,我可以查看您的文件。查看我的stackoverflow个人资料,了解如何与我联系。我不能帮助pdfbox,但也许看看错误在哪里会有所帮助。