You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 13:53:18