2017-11-20 9 views
3

私はオンラインからいくつかのコードを取得しており、彼らは私にフォントサイズを提供しています。 TextRenderInfoがどのようにテキストを読み込んでいるのか分かりませんでした。私はrenderInfo.GetText()を試してみましたが、文字の乱数、時には3文字、時には2文字以上またはそれ以下を与えています。私はrenderInfoがどのようにデータを読み込んでいるのか知る必要がありますか?TextRenderInfoはどのようにiTextSharpで動作しますか?

私の意図は、PDFからすべての行と段落を区切り、フォントサイズ、フォントスタイルなどのプロパティを個別に読み取ることです。ご意見がありましたら、それらに言及してください。

using System;  
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using iTextSharp.text.pdf.parser; 
using iTextSharp.text.pdf; 

namespace FontSizeDig1 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 
     // reader ==>     http://itextsupport.com/apidocs/itext5/5.5.9/com/itextpdf/text/pdf/PdfReader.html#pdfVersion 
     PdfReader reader = new PdfReader(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "document.pdf")); 
     TextWithFontExtractionStategy S = new TextWithFontExtractionStategy();//strategy==> http://itextsupport.com/apidocs/itext5/5.5.9/com/itextpdf/text/pdf/parser/TextExtractionStrategy.html 
    // for (int i = 1; i <= reader.NumberOfPages; i++) 
    // { 
      string F = iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(reader, 1/*i*/, S); 
      // PdfTextExtractor.GetTextFromPage(reader, 6, S) ==>> http://itextsupport.com/apidocs/itext5/5.5.9/com/itextpdf/text/pdf/parser/PdfTextExtractor.html 
      Console.WriteLine(F); 


     // } 
     Console.ReadKey(); 
     //this.Close(); 
    } 
} 


public class TextWithFontExtractionStategy : iTextSharp.text.pdf.parser.ITextExtractionStrategy 
{ 

    //HTML buffer 
    private StringBuilder result = new StringBuilder(); 

    //Store last used properties 
    private Vector lastBaseLine; 
    private string lastFont; 
    private float lastFontSize; 

    //http://api.itextpdf.com/itext/com/itextpdf/text/pdf/parser/TextRenderInfo.html 
    private enum TextRenderMode 
    { 
     FillText = 0, 
     StrokeText = 1, 
     FillThenStrokeText = 2, 
     Invisible = 3, 
     FillTextAndAddToPathForClipping = 4, 
     StrokeTextAndAddToPathForClipping = 5, 
     FillThenStrokeTextAndAddToPathForClipping = 6, 
     AddTextToPaddForClipping = 7 
    } 



    public void RenderText(iTextSharp.text.pdf.parser.TextRenderInfo renderInfo) 
    { 
     string curFont = renderInfo.GetFont().PostscriptFontName; // http://itextsupport.com/apidocs/itext5/5.5.9/com/itextpdf/text/pdf/parser/TextRenderInfo.html#getFont-- 
     //Check if faux bold is used 
     if ((renderInfo.GetTextRenderMode() == 2/*(int)TextRenderMode.FillThenStrokeText*/)) 
     { 
      curFont += "-Bold"; 
     } 

     //This code assumes that if the baseline changes then we're on a newline 
     Vector curBaseline = renderInfo.GetBaseline().GetStartPoint(); 
     Vector topRight = renderInfo.GetAscentLine().GetEndPoint(); 
     iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(curBaseline[Vector.I1], curBaseline[Vector.I2], topRight[Vector.I1], topRight[Vector.I2]); 
     Single curFontSize = rect.Height; 



     //See if something has changed, either the baseline, the font or the font size 
     if ((this.lastBaseLine == null) || (curBaseline[Vector.I2] != lastBaseLine[Vector.I2]) || (curFontSize != lastFontSize) || (curFont != lastFont)) 
     { 
      //if we've put down at least one span tag close it 
      if ((this.lastBaseLine != null)) 
      { 
       this.result.AppendLine("</span>"); 
      } 
      //If the baseline has changed then insert a line break 
      if ((this.lastBaseLine != null) && curBaseline[Vector.I2] != lastBaseLine[Vector.I2]) 
      { 
       this.result.AppendLine("<br />"); 
      } 
      //Create an HTML tag with appropriate styles 
      this.result.AppendFormat("<span style=\"font-family:{0};font-size:{1}\">", curFont, curFontSize); 
     } 

     //Append the current text 

     this.result.Append(renderInfo.GetText()); 
     Console.WriteLine("me=" + renderInfo.GetText());//by imtiaj 




     //Set currently used properties 
     this.lastBaseLine = curBaseline; 
     this.lastFontSize = curFontSize; 
     this.lastFont = curFont; 
    } 

    public string GetResultantText() 
    { 
     //If we wrote anything then we'll always have a missing closing tag so close it here 
     if (result.Length > 0) 
     { 
      result.Append("</span>"); 
     } 
     return result.ToString(); 
    } 

    //Not needed 
    public void BeginTextBlock() { } 
    public void EndTextBlock() { } 
    public void RenderImage(ImageRenderInfo renderInfo) { } 


} 

}

答えて

3

このPDFを見てみましょう:

enter image description here

あなたは何を見ていますか?

私は、次を参照してください。

Hello Worldの こんにちは人々

さて、このファイルを解析してみましょうか?あなたは何を期待していますか?

あなたは、おそらく期待:

Hello Worldの こんにちは人々

私はしないでください。

これはあなたと私が違うところです。その違いは、なぜこの質問をするのかを説明することです。

私は何を期待していますか?

まあ、私は最初のページのコンテンツストリームにおいて、より具体的には、PDF内を調べことから始めましょう:

enter image description here

私は4つのコンテンツストリーム内の文字列を参照してください。ldWor、​​を、およびHe(この順序で)。私も座標を参照してください。 、私はすぐにどこでも「こんにちは人々」を参照していないが、私は/Xf1という名前のフォームのXObjectへの参照を参照しています

Hello Worldの

:これらの座標を使用して、私が示されているものを構成することができます

enter image description here

Woohoo:それでは、そのフォームのXObjectを調べてみましょう!私は運が良かった、 "こんにちは人"は、ドキュメント内に単一の文字列値として格納されています。私は人間の目で見ることができる実際のテキストを構成するために座標を見る必要はありません。

ご質問ありがとうございます。「renderInfoがどのようにデータを読み込んでいるか知っておく必要がある」と言われています。デフォルトでは、iTextはすべての文字列を発生順にページから読み込みます。​​HeHello People

PDFが作成された方法に応じて、あなたが読みにくい(Hello Peopleを)読みやすい出力、または出力を持つことができる(ldWor、​​、He)。 [ldWor、​​、Heは] [He、​​、World]として提示しますが、同じ行に属する部分のどちらを検出し、どの行されるようにiTextのは、これらすべてのスニペットを並べ替える「戦略」が付属しています同じ段落に属している、あなたがする必要があります何かです。

注:iTextグループのには、すでに多くの時間を節約できる閉鎖ソースコードがあります。私たちはiTextライブラリの著作権者であるため、クローズドソースコードのお金を尋ねることができます。これは、iTextを無料で使用している場合(AGPLのため)、通常は行うことができないことです。しかし、あなたがiTextの顧客であれば、もっと多くのソースコードを公開する可能性があります。そのコードはあまりにも商業的価値があるので、私たちがそのコードを無料で提供するとは期待しないでください。

+0

ありがとうございます。もう1つ質問あります。なぜ彼らは2文字、3文字などですか? (ld、Wor、llo、He)として。それに続くシーケンスは何ですか? –

+0

これは奇妙な質問です。その "シーケンス"は、作者(または彼のオーサリングツール)が作った方法です。通常は実装の選択です。それがなぜその方法であるかを知る(または質問する)理由はありません、そこにありますか?私はあなたに尋ねると仮定しましょう:*あなたの名前はなぜイマイア・アハマドですか*あなたは何を答えますか?あなたのビジネスではないので(これはあなたのビジネスではないので、2つの文字、3つの文字などがあるからです)、これは攻撃的な質問です。あなたは答えることができます:それは私の両親が私に与えた名前なので、それは私の名前です(オーサリングツールがシーケンスを選んだのと同じです)。 –

+0

@imtiajahammad *「それはどのような順番ですか?」* - 任意の順序に従います。一度に各グリフを描画するPDF作成者がいますが、一度に全行を描画するものもあります。読書の順序で描かれているものもあれば、他の順序を使う​​ものもあります(そしてそうではありません。そのような順序の奇妙さには限界がありません)。 – mkl

関連する問題