2017-07-18 99 views
0

我正在使用iText重新创建Acrobat的标记树功能。使用MCID内容获取标记的内容

到目前为止,我已经设法得到标签结构。

我想弄清楚的最后一件事是如何让&解码内容流中标记的“标记内容”。

enter image description here

编辑:添加目的

这个问题的目的是要弄清楚如何访问内容流,具有MCID和解码的内容。

编辑2:添加iText的RUPS参考

下面的图像显示了我的树已经达到,红线指向MCID,我想获得它的内容。

enter image description here

编辑3:添加构建树

private void manipulate(PdfDictionary element, ItemCollection items) 
    { 
     if (element == null) 
     { 
      return; 
     } 

     ICollection<PdfName> val = element.KeySet(); 
     PdfObject tagName = element.Get(PdfName.S); 
     PdfObject elementType = element.Get(PdfName.Type); 

     string tn = ""; 

     if (tagName != null) 
     { 
      tn = ((PdfName)tagName).GetValue(); 
     } 
     else 
     { 
      tn = ((PdfName)elementType).GetValue(); 
     } 

     TreeViewItem tvI = new TreeViewItem() { Header = tn, IsExpanded = true }; 
     items.Add(tvI); 

     PdfArray kids = element.GetAsArray(PdfName.K); 
     if (kids == null) 
     { 
      return; 
     } 
     for (int i = 0; i < kids.Size(); i++) 
     { 
      PdfDictionary child = kids.GetAsDictionary(i); //Code change required here to detect MCID & get content, this line returns null when child is a MCID 
      manipulate(child, tvI.Items); 
     } 
    } 
} 

编辑4当前的代码:这样做的原因是重新创建的Acrobat的 “变量树” 的功能。

回答

2

根据您添加到问题中的标签,我看到您正在添加iText 7. iText 7有一个名为TaggedPdfReaderTool的类。这个类可以用来标记PDF文件转换成XML:

FileOutputStream outXml = new FileOutputStream("pdf_content.xml"); 
TaggedPdfReaderTool tool = new TaggedPdfReaderTool(document); 
tool.setRootTag("root"); 
tool.convertToXml(outXml); 
outXml.close(); 

XML将具有相同的结构是“标记结构”你已经能够提取。 XML标签内的内容将与PDF内容流中标记为“标签的一部分”的内容相对应。

给其他读者的重要信息:问题中的屏幕截图清楚地显示PDF已被标记。如果您在未加标签的PDF上尝试使用此代码段,则无法将内容转换为PDF。

更新:较低层次的方法

您还可以检查结构树这样的所有部分:process(document.getStructTreeRoot());

process()方法是这样的:

public static void process(IPdfStructElem elem) { 
    if (elem == null) return; 
    System.out.println(elem.getRole()); 
    System.out.println(elem.getClass().getName()); 
    if (elem instanceof PdfStructElem) { 
     processStructElem((PdfStructElem) elem); 
    } 
    if (elem.getKids() == null) return; 
    for (IPdfStructElem structElem : elem.getKids()) { 
     process(structElem); 
    } 
} 

public static void processStructElem(PdfStructElem elem) { 
    PdfDictionary page = elem.getPdfObject().getAsDictionary(PdfName.Pg); 
    if (page == null) return; 
    PdfStream contents = page.getAsStream(PdfName.Contents); 
    if (contents != null) { 
     System.out.println(new String(contents.getBytes())); 
    } 
    PdfArray array = page.getAsArray(PdfName.Contents); 
    System.out.println(array); 
} 

注页面的/Contents可以引用单个流或流的数组。在这个简短的片段中,我忽略了存储在流数组中的所有/Contents

这是我们使用的测试带标记的PDF执行这个时所透露的内容的一个例子:

EMC 
/Artifact BMC 
q 
0.01961 0.33333 0.52941 rg 
36 432.34 184.23 27.98 re 
f 
Q 
EMC 
/Span <</MCID 13>> BDC 
q 
BT 
/F2 12 Tf 
42 442.65 Td 
1 1 1 rg 
(The Library)Tj 
ET 
Q 
EMC 
/Artifact BMC 
q 
0.01961 0.33333 0.52941 rg 
36 399.11 184.23 27.98 re 
f 
Q 
EMC 
/Span <</MCID 14>> BDC 
q 
BT 
/F2 12 Tf 
42 409.42 Td 
1 1 1 rg 
(The Company)Tj 
ET 
Q 
EMC 
/Span <</MCID 15>> BDC 
q 
BT 
/F1 20 Tf 
227.73 472.71 Td 
(The Library)Tj 
ET 
Q 
EMC 
/Span <</MCID 16>> BDC 
q 
BT 
/F2 12 Tf 
229.23 440.45 Td 
(iText is a software developer toolkit that allows users to integrate PDF)Tj 
()Tj 
ET 
Q 
EMC 
/Span <</MCID 17>> BDC 
q 
BT 
/F2 12 Tf 
229.23 424.46 Td 
(functionalities within their applications, processes or products.)Tj 
ET 
Q 
EMC 
/Artifact BMC 
q 
0.01961 0.33333 0.52941 rg 
605.03 262.75 191.73 235.31 re 
f 
Q 
EMC 
/Span <</MCID 18>> BDC 
q 
BT 
/F1 16 Tf 
676.45 482.5 Td 
0.97647 0.76078 0.15294 rg 
(What?)Tj 
ET 
Q 
EMC 
/Span <</MCID 19>> BDC 
q 
BT 
/F2 12 Tf 
607.94 453.08 Td 
1 1 1 rg 
(iText is a software developer toolkit)Tj 
()Tj 
ET 
Q 
EMC 
/Span <</MCID 20>> BDC 
q 
BT 
/F2 12 Tf 
611.61 437.09 Td 
1 1 1 rg 
(that allows users to integrate PDF)Tj 
()Tj 
ET 
Q 
EMC 
/Span <</MCID 21>> BDC 
q 
BT 
/F2 12 Tf 
634.95 421.11 Td 
1 1 1 rg 
(functionalities within their)Tj 
()Tj 
ET 
Q 
EMC 
/Span <</MCID 22>> BDC 
q 
BT 
/F2 12 Tf 
669.96 405.12 Td 
1 1 1 rg 
(applications)Tj 
ET 
Q 
EMC 
/Span <</MCID 23>> BDC 
q 
BT 
/F1 16 Tf 
679.12 381.5 Td 
0.97647 0.76078 0.15294 rg 
(How?)Tj 
ET 
Q 
EMC 
/Span <</MCID 24>> BDC 
q 
BT 
/F2 12 Tf 
613.94 352.08 Td 
1 1 1 rg 
(By providing you with the tools to)Tj 
()Tj 
ET 
Q 
EMC 
/Span <</MCID 25>> BDC 
q 
BT 
/F2 12 Tf 
607.59 336.09 Td 
1 1 1 rg 
(create and manipulate a pdf in your)Tj 
()Tj 
ET 
Q 
EMC 
/Span <</MCID 26>> BDC 
q 
BT 
/F2 12 Tf 
668.96 320.11 Td 
1 1 1 rg 
(source code)Tj 
ET 
Q 
EMC 
/Span <</MCID 27>> BDC 
q 
BT 
/F1 16 Tf 
672.44 296.49 Td 
0.97647 0.76078 0.15294 rg 
(Really?)Tj 
ET 
Q 
EMC 
/Span <</MCID 28>> BDC 
q 
BT 
/F2 12 Tf 
673.64 267.06 Td 
1 1 1 rg 
(Yes really!)Tj 
ET 
Q 
EMC 

的一切,是不是BMC/EDCBDC/EDC运营商之间没有标记。您正在寻找标有MCID的内容。

在评论中,我解释说最好使用不同的方法。最好解析每个页面的内容流(只有一次),并将所有遇到的对象映射到结构树中的元素。

用你的方法,你必须一遍又一遍地为每个结构元素解析页面的内容流。这需要更多的处理。

+0

感谢您的建议。但我仍然想知道如何访问内容流并对其内容进行解码。 – PrivatMamtora

+0

你有没有听说过iText RUPS? –

+0

是的,我一直在使用它作为一个调试工具。请参阅编辑。 – PrivatMamtora