5

Railsを使用して既存のPDFにテキストを追加したいので、次のようにしました。

filename = "#{Rails.root}/app/assets/images/sample.pdf"
Prawn::Document.generate("#{Rails.root}/app/assets/images/full_template.pdf", :template => filename) do
  text "Test", :align => :center
end

また、full_template.pdfを開くと、テンプレートPDFとテキスト「テスト」がありますが、このテキストは、ミラーを使用して書かれたかのように、間違った方向に書かれています。

ここで2つのPDFドキュメントを見つけることができます:

オリジナル: http ://www.sebfie.com/wp-content/uploads/sample.pdf

生成: http ://www.sebfie.com/wp-content/uploads/full_template.pdf

4

2 に答える 2

9

見てみましょう... [PDFデバッグモードへの切り替え]

まず、「PDFファイルの構造的でコンテンツを保持する変換を行う」コマンドラインユーティリティ(自己記述)を使用して、 full_template.pdfを解凍します。qpdf

qpdf --qdf full_template.pdf qdf---test.pdf

結果のqdf---test.pdfは、すべてのストリームが解凍されるため、通常のテキストエディターでより簡単に分析できるようになりました。

文字列「est」を検索すると、次の行が見つかります。

[(T) 120 (est)] TJ

もう少し調べてみると(そして、qpdfその出力に散りばめられた非常に役立つコメントを見ると!)、これがわかります。元のPDFでミラーリングされた文字列「Test」が表示されるPDFオブジェクトは22番です。これは完全に別のオブジェクトです。ファイルの残りのテキスト、および埋め込まれていないHelveticaフォントを使用するのはこのファイルだけです。

それでは、元のファイルとは別にそれを抽出しましょう。

qpdf --show-object=22 --filtered-stream-data full_template.pdf 

 q
 /DeviceRGB cs
 0.000 0.000 0.000 scn
 /DeviceRGB CS
 0.000 0.000 0.000 SCN
 1 w
 0 J
 0 j
 [ ] 0 d

 BT
 286.55 797.384 Td
 /F3.0 12 Tf
 [<54> 120 <657374>] TJ
 ET

 Q

OK、ここでピース[(T) 120 (est)] TJはとして表示され[<54> 120 <657374>] TJます。コマンドを使用してこれを確認します。これにより、 asciiASCII<->Hexテーブルが出力されます。その表は確認します:

T  54
e  65
s  73
t  74

他の演算子はどういう意味ですか?それらは、公式のISO 32000 PDF-1.7仕様、付録A、「オペレーターの概要」で調べます。ここに、次の情報があります。

 q   : gsave
 Q   : grestore
 cs  : setcolorspace for nonstroking ops
 CS  : setcolorspace for stroking ops
 scn : setcolor for nonstroking ops
 SCN : setcolor for stroking ops
 w   : setlinewidth
 j   : setlinejoin
 J   : setlinecap
 d   : setdash
 BT  : begin text object
 Td  : move text position
 Tf  : set text font and size
 TJ  : show text allowing individual glyph positioning
 Tj  : show text
 ET  : end text object

これまでのところ疑わしいことは何もありません...

ただし、元のページコンテンツが表示される他のオブジェクト、オブジェクト番号5を見ると、違いがわかります。例えば:

1 0 0 -1 -17.2308 -13.485 Tm
<0013001c001200130018001200140015> Tj

Tjここでは、 (テキストを表示)の各単一アクションの前に、Tmオペレーター(これは何ですか?!?)が機能しています。TmPDF仕様も調べてみましょう。

 Tm  : set text matrix and text line matrix

ただし、奇妙なのは、このマトリックスが1 0 0 -1(より一般的なのではなく1 0 0 1)を使用していることです。これにより、テキストが上下逆にミラーリングされます。

ちょっと待って!?!

元のテキストコンテンツはミラーリングテキストマトリックスでストロークされていますが、それでも正常に表示されますか?しかし、追加したテキストはそれ自体のテキストマトリックスを使用していませんが、ミラーリングされているように見えますか?何が起こっている?!

これ以上追跡するつもりはありません。ただし、私の想定では、元のPDFの内臓のどこかで、オーサリングソフトウェアが「拡張グラフィックス状態」を定義し、デフォルトですべてのストローク操作がミラーリングされます。

セバスチャン、あなたは何も悪いことをしていないようです-あなたはテストオブジェクトの選択に不運で、かなり奇妙なものに恵まれました。最初に他のPDFで「エビ」の実験を続けてみてください...

qdf --- test.pdfのこの行を置き換えることで、 full_template.pdfを「修正」できます。

286.55 797.384 Td

これによって:

1 0 0 -1 286.55 797.384 Tm

次に、最後のqdfコマンドを実行して、(編集によって破損した)PDF相互参照テーブルとストリームの長さを修正します。

qpdf qdf --- test.pdf full_template --- fixed.pdf

コンソール出力には、必要な操作が表示されます。

  WARNING: qdf---test.pdf: file is damaged
  WARNING: qdf---test.pdf (file position 151169): xref not found
  WARNING: qdf---test.pdf: Attempting to reconstruct cross-reference table
  WARNING: qdf---test.pdf (object 8 0, file position 9072): attempting to recover stream length
  qpdf: operation succeeded with warnings; resulting file may have some problems

「固定」PDFには、ミラーリングされていないテキストが表示されます。

于 2012-08-23T10:06:10.757 に答える
1

プルリクエストがマージされたため、この問題はprawn-templatesgemで修正されました。修正は、PDFにコンテンツを追加する前にグラフィックスの状態をリセットすることでした。

これは、GoogleChromeとGoogleDocsがすべてのコンテンツを垂直方向に反転する変換行列を使用してPDFをエクスポートするために発生していました。デフォルトでは、PDFは左下隅からレンダリングされます。Googleのカスタム変換は、PDFの左上隅から座標を計算できることを意味します。これは、私にとってより理にかなっています。

PS非常に有益な回答をしてくれた@KurtPfeifleに感謝します!その情報がなければ、私はここまで到達できなかったでしょう。

于 2017-10-03T10:57:35.997 に答える