2013-03-13 106 views
5

我正在嘗試閱讀this使用C#中的itextsharp進行PDF轉換,將PDF轉換爲word文件。還需要維護表格格式和字體 當我嘗試使用英文pdf時,它會完美的工作,但使用一些印度語言,如印地文,馬拉地語它不工作。使用itextsharp閱讀PDF,其中PDF語言非英語

public string ReadPdfFile(string Filename) 
     { 

      string strText = string.Empty; 
      StringBuilder text = new StringBuilder(); 
      try 
      { 
       PdfReader reader = new PdfReader((string)Filename); 
       if (File.Exists(Filename)) 
       { 
        PdfReader pdfReader = new PdfReader(Filename); 

        for (int page = 1; page <= pdfReader.NumberOfPages; page++) 
        {      ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy(); 
         string currentText = PdfTextExtractor.GetTextFromPage(pdfReader, page, strategy); 

         text.Append(currentText); 
         pdfReader.Close(); 
        } 
       } 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
      textBox1.Text = text.ToString(); 
      return text.ToString(); ; 
     } 
+2

不幸的是,你只是說*它不工作*,但沒有出錯。儘管如此,當用Acrobat Reader從文檔中複製和粘貼時,我會看到明顯與原始PDF內容不同的字符。由於Acrobat Reader具有相當不錯的文本提取機器,我認爲PDF中的印度語文本並不包含文本提取所需的所有必要信息,而不是OCR。 – mkl

+0

@mkl感謝您的回覆問題是它正在讀字मतदरर實際的詞是मतद|र。這正在發生在pdf中的所有單詞。所以這個詞的實際意義就改變了。你對這個問題有什麼建議? –

+1

我會看看PDF。但是即使Adobe閱讀器沒有正確地從PDF中提取文本,我認爲PDF中的印度語文本並不包含文本提取所需的所有必要信息,而不是OCR。 – mkl

回答

13

我檢查了您的文件,特別關注您的樣本「मतद|र」在文檔頁面的頂部行中被解壓爲「मतदर」。

簡而言之:

您的文檔本身例如提供信息頭條中的字形「मतद|र」代表文字「मतदर」。您應該向文檔的來源索要一個文檔版本,其中的字體信息沒有誤導性。如果這是不可能的,你應該去OCR。

詳細地:

第一頁的頂部線是由頁面內容流中的下面的操作中產生:

/9 280 Tf 
(-12"!%$"234%56*5) Tj 

第一行選擇指定的字體/9大小爲280(頁面開始時的操作將所有內容都縮放爲0.05;因此,有效大小是您在文件中觀察到的14個單位)。

第二行導致字形被打印。這些字形在括號中使用該字體的自定義編碼引用。

當程序嘗試提取文本時,必須使用字體中的信息從這些字形引用中推導出實際字符。

242 0 obj<< 
    /Type/Font/Name/9/BaseFont 243 0 R/FirstChar 33/LastChar 94 
    /Subtype/TrueType/ToUnicode 244 0 R/FontDescriptor 247 0 R/Widths 248 0 R>> 
endobj 
243 0 obj/CDAC-GISTSurekh-Bold+0 
endobj 
247 0 obj<< 
    /Type/FontDescriptor/FontFile2 245 0 R/FontBBox 246 0 R/FontName 243 0 R 
    /Flags 4/MissingWidth 946/StemV 0/StemH 0/CapHeight 500/XHeight 0 
    /Ascent 1050/Descent -400/Leading 0/MaxWidth 1892/AvgWidth 946/ItalicAngle 0>> 
endobj 

所以沒有/編碼元素,但至少有一個參考/:

字體/9您的PDF的第一頁上使用這些對象定義ToUnicode地圖。因此,提取文本的程序必須依賴於給定的映射。

<21> <21> <0930> 
<22> <22> <0930> 
<24> <24> <091c> 
<25> <25> <0020> 
<2a> <2a> <0031> 
<2d> <2d> <092e> 
<31> <31> <0924> 
<32> <32> <0926> 
<33> <33> <0926> 
<34> <34> <002c> 
<35> <35> <0032> 
<36> <36> <0030> 

(已經在這裏,您可以:

通過/ToUnicode引用的流提取文本( 「!%$」 -12 234%56 * 5)當包含感興趣以下映射看到,多個字符代碼被映射到相同的Unicode代碼點...)

因此,文本提取必須導致:

- = 0x2d -> 0x092e = म 
1 = 0x31 -> 0x0924 = त 
2 = 0x32 -> 0x0926 = द 
" = 0x22 -> 0x0930 = र instead of | 
! = 0x21 -> 0x0930 = र 
% = 0x25 -> 0x0020 = 
$ = 0x24 -> 0x091c = ज 
" = 0x22 -> 0x0930 = र 
2 = 0x32 -> 0x0926 = द 
3 = 0x33 -> 0x0926 = द 
4 = 0x34 -> 0x002c = , 
% = 0x25 -> 0x0020 = 
5 = 0x35 -> 0x0032 = 2 
6 = 0x36 -> 0x0030 = 0 
* = 0x2a -> 0x0031 = 1 
5 = 0x35 -> 0x0032 = 2 

因此,文本iTextSharp(以及Adobe Reader!)從第一個文檔頁面的標題中提取正是其字體信息中聲明的文檔正確的文本。

由於原因是字體定義中誤導性的映射信息,所以在整個文檔中存在錯誤解釋並不令人驚訝。

+0

,所以只有OCR纔是解決方案?怎麼運行的? –

+1

更好的解決方案將是一個適當的源文件。 OCR通過​​將PDF頁面呈現爲位圖圖形(例如,使用PDFBox)並將OCR應用於它們來工作。我沒有經驗,哪種OCR軟件適合這項工作。如果你覺得自己敢於接受,你可能想創建一些代碼,只渲染給定PDF中字體中包含的字形,OCR化它們,派生正確的**/ToUnicode **表,並將這些表添加到字體在各自的PDF中。 – mkl

+0

@mkl有沒有任何Java代碼來獲取ToUnicode包含的是(-12「!%$」234%56 * 5) –

4

正如@mkl所說,我們需要更多的信息來說明爲什麼事情不能正常工作。但我可以告訴你一些可能對你有幫助的事情。

首先,SimpleTextExtractionStrategy很簡單。如果你read the docs它,你會發現:

如果PDF呈現在非頂至底時尚的文字,這將導致不被它是如何出現在真實再現文本PDF

這意味着儘管PDF可能看起來應該從上到下閱讀,但它可能是按不同的順序書寫的。您引用的PDF實際上有第一個寫入的第二條視線。看到我的post here for a slightly smarter text extraction strategy,試圖從上到下返回文本。當我在你的PDF的第一頁上運行我的代碼時,它似乎正確地拉出了每一行。

其次,PDFs沒有表格的概念。他們只是在特定位置繪製了文字和線條,而這些都不相互關聯。這意味着你需要計算每一行並建立自己的表格概念,在iTextSharp中找不到任何代碼可以爲你做到這一點。我個人甚至不打算寫一個。

三,文字提取是爲了拉文字,與字體無關。如果你想要的話,你必須自己構建邏輯。請參閱我的post here以瞭解其基本開局。

+2

+1;一個評論,儘管:SimpleTextExtractionStrategy雖然很簡單,對於某些文檔可能仍然是最佳選擇;特別是在多列文本沒有容易識別的列分隔的情況下,只要文本已按照閱讀順序添加到內容中。一個基本上必須決定每個文件的基礎。 – mkl

+0

@Chris Haas感謝您的回覆問題是它正在讀字मतदर凡實際的字是मतद|र。這正在發生在pdf中的所有單詞。所以這個詞的實際意義就改變了。 –

+0

正如@mkl所說,即使Adobe的程序認爲它是錯誤的文字說明可能存在一個很大的問題 –