如何通过iText 7获取PDF的Accessibility、Alternate Text属性(同Adobe Pro)
使用iText 7提取PDF的无障碍属性与替代文本
要获取和Adobe Pro等工具一致的PDF无障碍信息(包括替代文本),需要从图像XObject、文档结构树、表单字段、文档元数据这几个维度入手,以下是具体实现方法:
一、提取图像的替代文本
图像的替代文本通常存储在图像XObject的/Alt条目下,遍历每页资源中的XObject即可获取:
PdfDocument pdfDoc = new PdfDocument(new PdfReader("input.pdf")); for (int pageNum = 1; pageNum <= pdfDoc.getNumberOfPages(); pageNum++) { PdfPage page = pdfDoc.getPage(pageNum); PdfDictionary resources = page.getPdfObject().getAsDictionary(PdfName.Resources); if (resources == null) continue; PdfDictionary xObjects = resources.getAsDictionary(PdfName.XObject); if (xObjects == null) continue; for (PdfName xObjName : xObjects.keySet()) { PdfObject xObj = xObjects.get(xObjName); if (!(xObj instanceof PdfStream)) continue; PdfStream imgStream = (PdfStream) xObj; if (!PdfName.Image.equals(imgStream.getAsName(PdfName.Subtype))) continue; // 读取图像替代文本 PdfString altText = imgStream.getAsString(PdfName.Alt); if (altText != null) { System.out.printf("页面 %d 图像替代文本: %s%n", pageNum, altText.toUnicodeString()); } } } pdfDoc.close();
二、通过结构树提取无障碍信息
Adobe Pro显示的大部分无障碍内容来自PDF的结构树(StructTree),这里包含了元素的角色、替代文本、描述等信息,需要递归遍历结构元素:
PdfDocument pdfDoc = new PdfDocument(new PdfReader("input.pdf")); PdfStructTreeRoot structRoot = pdfDoc.getStructTreeRoot(); if (structRoot != null) { traverseStructElements(structRoot.getKids()); } pdfDoc.close(); // 递归遍历结构元素 private static void traverseStructElements(List<PdfStructElem> elements) { for (PdfStructElem elem : elements) { // 获取元素角色 PdfName role = elem.getRole(); System.out.printf("结构角色: %s%n", role.getValue()); // 获取替代文本 PdfString altText = elem.getPdfObject().getAsString(PdfName.Alt); if (altText != null) { System.out.printf("替代文本: %s%n", altText.toUnicodeString()); } // 获取元素描述 PdfString desc = elem.getPdfObject().getAsString(PdfName.Desc); if (desc != null) { System.out.printf("元素描述: %s%n", desc.toUnicodeString()); } // 递归处理子元素 List<PdfStructElem> kids = elem.getKids(); if (kids != null && !kids.isEmpty()) { traverseStructElements(kids); } } }
三、提取表单字段的无障碍文本
表单字段的替代文本(工具提示)存储在/TU条目下,可通过PdfAcroForm获取:
PdfDocument pdfDoc = new PdfDocument(new PdfReader("input.pdf")); PdfAcroForm acroForm = PdfAcroForm.getAcroForm(pdfDoc, false); if (acroForm == null) { pdfDoc.close(); return; } Map<String, PdfFormField> fields = acroForm.getFormFields(); for (Map.Entry<String, PdfFormField> entry : fields.entrySet()) { PdfFormField field = entry.getValue(); PdfString tuText = field.getPdfObject().getAsString(PdfName.TU); if (tuText != null) { System.out.printf("字段 %s 替代文本: %s%n", entry.getKey(), tuText.toUnicodeString()); } } pdfDoc.close();
四、获取文档级无障碍元数据
文档级的无障碍标记、语言等信息存储在目录字典中:
PdfDocument pdfDoc = new PdfDocument(new PdfReader("input.pdf")); PdfCatalog catalog = pdfDoc.getCatalog(); // 检查文档是否标记为无障碍 PdfDictionary markInfo = catalog.getAsDictionary(PdfName.MarkInfo); if (markInfo != null && markInfo.getAsBoolean(PdfName.Marked)) { System.out.println("文档已标记为无障碍文档"); } // 获取文档语言 PdfString lang = catalog.getAsString(PdfName.Lang); if (lang != null) { System.out.printf("文档语言: %s%n", lang.toUnicodeString()); } pdfDoc.close();
关键注意事项
- 部分图像的替代文本仅存储在结构树中,而非图像XObject本身,因此需要结合两种提取方式才能覆盖所有场景。
- 如果文档使用了自定义角色映射(
/RoleMap),需要先解析映射关系才能得到标准角色名称。 - 复杂文档的无障碍信息可能嵌套在多层结构元素中,递归遍历是必要的。
内容的提问来源于stack exchange,提问作者Andre Rubnikowich
相关产品推荐
相关产品推荐

