1

私は、ユーザーがレイヤーを使用してPDFにテキストを挿入できるアプリを構築しています。

PDF ページ内のテキストの位置は、 JPanel 内のICEPdfを使用して PDF をレンダリングするアプリを使用して設定できます。レイヤーの位置とサイズを選択すると、アプリはiText (v. 5.3.2) を使用してレイヤーを PDF にレンダリングします。

私が直面している問題は、Swing からのフォント レンダリングが、PDF の最終結果と見た目が異なることです。

同じバウンディング ボックス内で Helvetica プレーン フォントを使用したスクリーン ショットを次に示します。

Swing を使用したテキストのレンダリング:

protected void paintComponent(Graphics g){
      //for each line...
      g.drawString(text, b0, b1);
      //b0 and b1 are computed from the selected bounding box for the text
}

私はこれを持っています:

スイングレンダリング

iText を使用したテキストのレンダリング:

PdfTemplate t; //PdfTemplate is created elsewhere
ColumnText ct = new ColumnText(t);
ct.setRunDirection(PdfWriter.RUN_DIRECTION_NO_BIDI);
ct.setSpaceCharRatio(1);
ct.setSimpleColumn(new Phrase(text, font), b0, b1, b3, b4, font.getSize(), Element.ALIGN_BOTTOM); 
//b0, b1, b2 and b3 are the bounding box of the text
ct.go();

私はこれを持っています:

PDF レンダリング

問題は、Swing と iText でフォントをまったく同じようにレンダリングするにはどうすればよいかということです。Swing や iText を微調整できるので、どのコードが変更されても、ユーザーにとって真のWYSIWYGエクスペリエンスが必要です。

他のフォントやタイプで試してみましたが、それでもいくつか違いがあります。私はいくつかの設定が欠けていると思います。

ありがとう。

4

2 に答える 2

2

編集:

Java のフォントはピクセルで測定されますが、iText はポイントで測定され、1 インチあたり 72 ポイントであり、標準的な Windows マシンでは 1 インチあたり 96 ピクセル/dpi であることがわかっています。

まず、ポイントとピクセルの違いを見つける必要があります。

difference = 72 / dpi
      0.75 = 72 / 96

次に、Java フォント サイズに差を掛けて iText フォント サイズを取得します。Java フォント サイズが 16 の場合、96dpi で使用する場合、iText フォント サイズは 12 になります。

iTextFontSize = difference x javaFontSize
           12 = 0.75 x 16

Windows マシンでは、多くの場合 96dpi が標準ですが、常にそうであるとは限らないことに注意してください。異なるマシンごとに計算する必要があります。


元の投稿

違いはレンダリングヒントによるものだと思います。

解決策 1:

それを行う最善の方法は、バッファリングされた画像にすべてを描画することです。次に、バッファリングされた画像がスイングコンポーネントに描画され、まったく同じバッファリングされた画像がPDFにも描画されるため、それらの間に違いはありません。

別のアイデア:

同様に機能しない可能性がありますが、既存のコードでより適切に機能するもう 1 つのアイデアは、swing コンポーネントのコンテンツをバッファリングされた画像に直接描画し、バッファリングされた画像を PDF に描画することです。

以下は、いくつかの異なるレンダリング ヒントを使用して、JPanel のコンテンツをバッファリングされた画像に描画する簡単な例です。(スイングの構成要素に合わせてヒントを変更してください)

public BufferedImage createImage(JPanel panel)
{
    BufferedImage swingComponent = new BufferedImage(
            panel.getHeight(), panel.getWidth(), 
            BufferedImage.TYPE_INT_RGB);

    Graphics2D g = swingComponent.createGraphics();

    g.setRenderingHint(RenderingHints.KEY_RENDERING,
                       RenderingHints.VALUE_RENDER_QUALITY);

    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                       RenderingHints.VALUE_ANTIALIAS_ON);

    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                       RenderingHints.VALUE_INTERPOLATION_BILINEAR);

    g.dispose();
    return swingComponent; //print this to your PDF
}
于 2012-08-28T22:34:37.760 に答える
0

問題は、Swing と iText でフォントをまったく同じようにレンダリングするにはどうすればよいかということです。

まったく同じ?非常に少ない。両方に同じフォント特性を指定すると仮定しても、レンダリングに違いが生じる可能性があります。

PDF ファイル (実際にはテキスト フレーズ) にはフォント情報 (ファミリ、サイズ、スタイルなど) が保持されていますが、テキストをデバイスにレンダリングするのは PDF リーダーです。使用するプログラムに応じて、プラットフォームのレンダラーを使用するか、独自のレンダラーを選択できます。

私の知る限り、Java Swing は、基盤となるプラットフォームのレンダラーとは異なり、独自のフォント レンダリング エンジンを使用します。これにより、プラットフォーム間で見た目の一貫性が向上しますが、テキストが他のプログラムと同じようにレンダリングされる可能性はほとんどなくなります。

それを知っていると、選択肢は限られています。

  • Swing フォント レンダリングも使用する PDF リーダーを使用します。それはかなり限定的な解決策です。

  • プラットフォームのレンダリング エンジンを使用して Swing に描画します。それは難解な作業のように聞こえますが、SWT が解決したであろうことのようにも思えます。SWT コンポーネントを埋め込むことはできますか?

于 2014-10-18T20:23:11.497 に答える