Skip to main content

iTextSharpでウォーターマーク出力する時の注意

いやー、超ハマりました。
iTextSharpを使って既存のpdfにテキストと画像をウォーターマークとして付与し、出力するという処理を作っていたのですが、一部のpdfで指定した座標に出力できないといった事象が多発していました。
しばらくの間原因がつかめず半ば放置していたのですが、原因判明。
pdfを作成した環境なのか作り方なのかはわからないのですが、用紙サイズが狂っていました。

PdfReaderのインスタンスからGetPageSize(ページ番号)をするとiTextSharp.text.Rectangle型の情報を取得することができます。
取得した情報の中にLeftだのBottomだのといったプロパティがあるのですが、狂っていない(?)pdfだと0になっています。
ここが0以外の数値になっていると、PdfStamperのSetTextMatrixで指定した座標からその分だけずれて出力されてしまいます。

例えばGetPageSizeで取得した情報のLeftが-30、Bottomが50として
SetTextMatrix( x:=10, y:=120 )
をいうメソッドを走らせると、x=40、Bottom=70の位置に出力しようとします。
つまり(LeftもしくはBottom * -1)分だけ左あるいは下に動いてしまうわけです。

というわけで対策としては、SetTextMatrixメソッドでの座標指定時に、このずれた部分で補正してやることです。
VB.NETコードで表現すると・・・(何処かにシンタクスエラーがあるかもしれません)



Dim bf As BaseFont = New BaseFont.CreateFont("C:\Windows\Fonts\msgothic.ttc,0", BaseFont.IDENTITY_H, True)
Dim pr As New PdfReader(path)
Dim fs As New FileStream(outputpath, CreateNew)
Dim ps As New PdfStamper(pr, fs)
Dim under As PdfContentByte = Nothing

Dim underImg As PdfContentByte = Nothing
Dim img = iTextSharp.text.Image.GetInstance(imgpath)

Dim idx As Integer = 0

'全ページにウォーターマークを入れる場合
For idx = 1 To pr.NumberOfPages

    'テキストの場合
    'PdfContentByteを取得
    under = ps.GetUnderContent(idx)
    'テキスト出力開始
    under.BeginText()
    'ベースフォント設定
    under.SetFontAndSize(bf, 11)
    'GetPageSizeでの補正を行いつつテキスト出力開始位置を指定
    under.SetTextMatrix(10 + pr.GetPageSize(idx).Left, 120 + pr.GetPageSize(idx).Bottom)
    'テキスト出力
    under.ShowText("テスト")
    'テキスト出力終了
    under.EndText()

    '画像の場合
    'PdfContentByteを取得
    underImg = ps.GetUnderContent(idx)
    'GetPageSizeでの補正を行いつつ画像出力開始位置(左下)を指定
    img.SetAbsolutePosition(100 + pr.GetPageSize(idx).Left, 300 + pr.GetPageSize(idx).Bottom)
    '画像出力
    underImg.AddImage(img)

Next
ps.Close

・・・という感じになります。

これでとりあえず指定した位置に出力することが可能となりました。
もし同様にハマっている方、参考にしてください。

Comments