開発者ブログ

PDFをPitaliumで比較する

Last modified by msakai on 2016/09/13, 19:02

業務アプリケーションでは、帳票をPDFとして出力するケースがよく見られます。PDFのテキスト抽出や画像化ができるライブラリと組み合わせることで、出力した帳票PDFの表示結果が正しいかどうかも合わせてテストすることが可能です。

PDFのテスト

Apache PDFBox

Apache PDFBox(https://pdfbox.apache.org/) は、PDFを扱うことができるオープンソースのJavaライブラリです。
PDFからテキストを抽出する機能や、PDFを画像として保存する機能を備えています。本サンプルではこちらを使用します。

サンプルプロジェクト

本サンプルのコードは、サンプルプロジェクトに含まれています。

GitHubからpitalium-sampleプロジェクトをチェックアウトし、
READMEに従ってivy_build.xmlを実行します。

サンプルコードを実行する

サンプルのPDFReadTest.java は、チェックアウトしたプロジェクトの com.htmlhifive.pitalium.sample.pdf パッケージ内にあります。
PDFReadTest.java は次のように動作します。

  1. SET_EXPECTEDモードで実行する
    • src/main/resources/environmentConfig.json で、execModeがSET_EXPECTEDになっていることを確認してから実行して下さい。
    • 実行すると、src/main/resources 内の同パッケージにある"sample_expected.pdf" が画像として出力されます。出力先はexportsディレクトリです。
  2. RUN_TESTモードで実行する
    • execModeをRUN_TESTに変更し、実行して下さい。
    • 実行すると、"sample_actual.pdf" が画像として出力されます。
    • さらに、"sample_expected.pdf" の画像と比較し、比較結果の差分画像がexportsディレクトリに出力されます。

diffImage.png

サンプルコードの解説

PDFを画像として保存する

PDFを画像として保存するには、PDFBoxのPDFRenderer#renderImageWithDPI()を使用します。

int numberOfPages = 0;

try (BufferedInputStream fileToParse = new BufferedInputStream(getClass().getResourceAsStream(fileName + ".pdf")); // (1)
     PDDocument pdf = PDDocument.load(fileToParse)) { // (2)
// 1ページ=1画像として全ページを保存
final PDFRenderer pdfRenderer = new PDFRenderer(pdf); // (3)
numberOfPages = pdf.getNumberOfPages();
 
for (int i = 0; i < numberOfPages; i++) {
final BufferedImage image = pdfRenderer.renderImageWithDPI(i, 300, ImageType.RGB); // (4)
if (!saveExportImage(image, fileName + i + ".png")) {
return -1;
}
}
}
  1. 対象のPDFファイルをBufferedInputStreamで読み込む。
  2. PDDocumentとしてロードする。
  3. PDDocumentを渡してRendererを作成する。
  4. RendererのrenderImageWithDPIメソッドを呼び出すと、BufferedImageに変換される。

Pitaliumで画像を比較する

Pitaliumでは、ImageUtilsクラスのメソッドを呼び出すことで、画像比較の機能のみを利用することができます。
ImageUtils#compare()で2枚の画像の差分を抽出し、ImageUtils#getDiffImage()で差分を可視化したdiff画像を生成します。

BufferedImage leftImage = readImage(EXPORT_FILE_PATH + "sample_expected" + i + ".png"); // (1)
BufferedImage rightImage = readImage(EXPORT_FILE_PATH + "sample_actual" + i + ".png");

DiffPoints diffPoints = ImageUtils.compare(leftImage, null, rightImage, null, null); // (2)

// 差分があれば差分画像を出力
if (diffPoints.isFailed()) { // (3)
final BufferedImage diffImage = ImageUtils.getDiffImage(leftImage, rightImage, diffPoints); // (4)
saveExportImage(diffImage, "diffImage.png");
Assert.fail("PDFが一致しません。");
}
  1. 比較する2枚の画像をBufferedImageとして読み込む。
  2. ImageUtils.compare() メソッドを呼び出し、2枚の画像を比較する。画像の差分の集合が返される。
  3. 差分の有無をチェックする。差分が無ければ、diffPoints.isSucceeded()の結果がtrueになる。差分がある場合は、diffPoints.isFailed()の結果がtrueになる。
  4. ImageUtils.getDiffImage() メソッドに2枚の画像と差分情報を渡し、diff画像を生成する。

Copyright (C) 2012-2017 NS Solutions Corporation, All Rights Reserved.