PDFテキスト文字列のエンコード 質問する

PDFテキスト文字列のエンコード 質問する

私は PDF のパーサー (テキスト抽出) に取り組んでいます。

ページが必要な場合Flate のデコード(zlib 圧縮から)、私のコードはコンテンツ ストリームを解凍することができ、次のような出力 (ストリーム オブジェクト) が得られます。

BT
56.8 721.3 Td 
/F2 12 Tf
[<01>2<0203>2<04>-10<0503>2<04>-2<0506070809>2<0A>1<0B>]TJ
ET

文字列配列(TJ のオペランド)に興味があります。

この配列には 16 進数でエンコードされた文字列が複数含まれているようですが、対応する 16 進数値は意味をなさないようです。代わりに、010203... のようなシーケンスが表示されます。これは lz77 圧縮の一種です。

  • PDF には複数のレベルの圧縮がありますか?
  • 上記の文字列配列からプレーンテキストを取得するにはどうすればよいですか?

ベストアンサー1

このような野心的なプロジェクトを始める前に、完了 公式 PDF-1.7 仕様警告:これは756ページの文書であり、約90の他の文書を参照しており、それらも「規範的な」PDF 用。

PDFソースコードをテキストコンテンツに逆変換するには、エンコーディングフォントによって使用されます。仕様で定義された 5 つの標準エンコーディングを使用できます。

  1. StandardEncoding
  2. MacRomanEncoding
  3. WinAnsiEncoding
  4. PDFDocEncoding
  5. MacExpertEncoding

それに加えて、CustomEncoding(これは、埋め込まれたフォントがサブセットであり、フォントで定義されたすべてのグリフではなく、ドキュメントに必要なグリフのみが含まれている場合に有効になります)。PDF/ToUnicode内にテーブルが定義されている場合にのみ、CustomEncode されたテキストを逆順にすることができます。その場合にのみ、エンコードされた文字を文字名に逆順にマップできます。

また、1つ、しかし、テキスト文字列を表示するために使用できる演算子:

  1. Tj:「テキストを表示」
  2. TJ:「テキストを表示し、個別のグリフ配置を許可します」
  3. ':「次の行に移動してテキストを表示」
  4. ":「単語と文字の間隔を設定し、次の行に移動してテキストを表示します」

さらに、テキスト文字列を表現する3つの異なる方法ここでは、文字列の例を示します"弦":

  1. (string): これは標準の印刷可能括弧内の ASCII 文字 (ラテン語/ASCII テキスト部分でのみ可能)。
  2. (\163\164\162\151\156\147): これは8進数文字コード(括弧内も含む)は、「付録 D (規範) 文字セットとエンコーディング」仕様書の。
  3. <737472696E67>: これは16進数エンコード山括弧内の文字コード。

テキスト抽出の問題は次のとおりです。

  1. 使用印刷可能なASCII文字(1.上記)および8進文字コード2.(上記)は混在可能です。以下はすべて、文字列の「正当な」表現です。"弦"(リストは完全ではありません!):

     (\163tring)Tj
     (\163\164\162\151\156g) Tj
     (st\162i\156g)  Tj
     ...
    
  2. 使用16進数でエンコードされた文字コード3.上記の表現も簡単ではありません。以下の表現はすべて同等だからです。

    <73 74 72 69 6E 67> TJ
    
    <73 7472 696E67> TJ
    
    <7 374 7 269 6E 67>TJ
    
    <73   74    72696E 67> TJ
    
    <73
      74 7
      2 69 6E 67>
    TJ
    

PDF 仕様で許可されている (または Adob​​e ビューアで許容されている) その他の奇妙な点については、たとえば以下も参照してください。

私自身、最近、手作業でコーディングした一連の PDF ファイルを作成しました。これは、欠落したテーブル、間違ったテーブル、操作されたテーブル、または正しい/ToUnicodeテーブルが、PDF からテキストへの逆変換の結果にどのように影響するかを示しています。


最後に、OP が提供した PDF ソース コードの小さなスニペットを見てみましょう。

BT
56.8 721.3 Td 
/F2 12 Tf
[<01>2<0203>2<04>-10<0503>2<04>-2<0506070809>2<0A>1<0B>]TJ
ET
  • BTETテキスト表示セクションの始まりと終わりを示す

  • 56.8 721.3 Td現在の点を座標に配置する「水平方向に56.8ポイント、垂直方向に721.3ポイント」

  • 12 Tfフォントサイズを 12 ポイントに設定します。

  • /F1使用するフォントをPDF文書内の他の場所で定義されているものに設定します。そのフォントはどこかでフォントエンコーディング(場合によっては/ToUnicodeテーブルも)。フォント エンコーディングによって、テキスト文字列に特定の文字コードが見つかった場合に描画するグリフの形状が決まります。

  • [<01>2<0203>2<04>-10<0503>2<04>-2<0506070809>2<0A>1<0B>]TJ

この最後の部分は、以下の部分に分解できます。

  • <01>2:は<01>最初の文字コードです。2「個々のグリフの配置」テキスト表示演算子を使用する場合に許可されますTJ
  • <0203>2: は<0203>2つの文字コードです。2again は「個々のグリフの配置」のためにTJ
  • <04>-10:は4<04>番目の文字コードです。-10「個々のグリフの配置」TJ
  • <0503>2:<05>は5番目の文字コード、<03>は3番目の文字コード(以前使用)です2「個々のグリフの配置」...

個々のグリフの位置: の個々のグリフの位置次のように動作します:

  • ポジティブ数字は次のグリフを(次のグリフまでのグリフ間隔を狭めます)。
  • ネガティブ数字は次のグリフを(次のグリフにスペースを追加します)。
  • 数字自体は、現在の単位の 1000 分の 1 を表すものとみなされます。

文字コードの意味: 最初、2 番目、3 番目、... 最後の文字コードの意味を知るには、/ToUnicodePDF の表でこれらを調べる必要があります。そのような表が埋め込まれていない場合は、運が悪いです。

テキストの抽出容易性をチェックする: PDF が簡単にテキスト抽出に適しているかどうかを確認するには、コマンドライン ツールを使用できますpdffonts。出力例を次に示します。

$ pdffonts sample.pdf
  name                      type          encoding     emb sub uni object ID
  ------------------------- ------------- ------------ --- --- --- ---------
  IADKRB+Arial-BoldMT       CID TrueType  Identity-H   yes yes yes     10  0
  SSKFGJ+ArialMT            CID TrueType  Custom       yes yes no      11  0

上記の例では、サブセット化されたフォントはSSKFGJ+ArialMTカスタム エンコーディングを使用しますが、/ToUnicodeという見出しの列に示されているように、PDF にはこのフォントがありませんuni。したがって、このフォントで表示されるテキストを抽出するのは簡単ではありません (抽出には手動のリバース エンジニアリングが必要になりますが、その後は PDF ページを「読み取る」こともできます)。

おすすめ記事