Cairo グラフィック ライブラリを使用して PDF ファイルを出力する CAD アプリケーションを作成しています。多くの単体テストでは、オブジェクトの予想されるバウンディング ボックスの計算など、実際に PDF ファイルを生成する必要はありません。ただし、コードを変更した後、生成された PDF ファイルが正しく「見える」ことを確認したいと考えています。これを行う自動化された方法はありますか?できるだけ自動化するにはどうすればよいですか?生成された各 PDF を視覚的に検査する必要がありますか? 髪を抜かずにこの問題を解決するにはどうすればよいですか?
5 に答える
(以下のアップデートも参照してください!)
Linuxでラップするシェルスクリプトを使用して同じことをしています
- ImageMagick の
compare
コマンド pdftk
ユーティリティ_- Ghostscript (オプション)
(これ.bat
を DOS/Windows 用のバッチ ファイルに移植するのは比較的簡単です。)
アプリケーションによって作成された「既知の正常な」参照 PDF がいくつかあります。コード変更後に新しく生成された PDF は、これらの参照 PDF と比較されます。比較はピクセル単位で行われ、新しい PDF として保存されます。この PDF では、変更されていないピクセルはすべて白で塗りつぶされ、異なるピクセルはすべて赤で塗りつぶされます。
構成要素は次のとおりです。
pdftk
このコマンドを使用して、複数ページの PDF ファイルを複数の単一ページの PDF に分割します。
pdftk reference.pdf burst output somewhere/reference_page_%03d.pdf
pdftk comparison.pdf burst output somewhere/comparison_page_%03d.pdf
比較
このコマンドを使用して、各ページの「差分」PDF ページを作成します。
compare \
-verbose \
-debug coder -log "%u %m:%l %e" \
somewhere/reference_page_001.pdf \
somewhere/comparison_page_001.pdf \
-compose src \
somewhereelse/reference_diff_page_001.pdf
ゴーストスクリプト
自動的に挿入されたメタ データ (現在の日付と時刻など) が原因で、PDF 出力は MD5hash ベースのファイル比較ではうまく機能しません。
真っ白なページで構成されるすべてのケースを自動的に検出したい場合は、bmp256
出力デバイスを使用してメタデータのないビットマップ形式に変換することもできます。これは、元の PDF (参照と比較)、または差分 PDF ページに対して行うことができます。
gs \
-o reference_diff_page_001.bmp \
-r72 \
-g595x842 \
-sDEVICE=bmp256 \
reference_diff_page_001.pdf
md5sum reference_diff_page_001.bmp
MD5sum が 595x842 PostScript ポイントの真っ白なページに期待するものであれば、単体テストは成功です。
アップデート:
ImageMagick からヒストグラム出力を生成することを以前に考えなかった理由がわかりませんcompare
...
以下は、2 つの異なるコマンドをチェーンするコマンド パイプラインです。
- 最初のものは、「白いピクセルは等しい、赤いピクセルは違います」
compare
形式を生成する上記と同じですが、ImageMagick 内部形式を出力するだけです。ファイルには書き込みませんが、stdoutに書き込みます。miff
- 2 つ目は、 stdin
convert
を読み取り、ヒストグラムを生成し、結果をテキスト形式で出力するために使用します。次の 2 行があります。- 白いピクセルの数を示すもの
- もう 1 つは赤のピクセル数を示します。
ここに行きます:
compare \
reference.pdf \
current.pdf \
-compose src \
miff:- \
| \
convert \
- \
-define histogram:unique-colors=true \
-format %c \
histogram:info:-
出力例:
56934: (61937, 0, 7710,52428) #F1F100001E1ECCCC srgba(241,0,30,0.8)
444056: (65535,65535,65535,52428) #FFFFFFFFFFFFCCCC srgba(255,255,255,0.8)
(サンプル出力は、これらのreference.pdfおよびcurrent.pdfファイルを使用して生成されました。)
このタイプの出力は、自動単体テストに非常に適していると思います。2 つの数値を評価すると、「赤のピクセル」のパーセンテージを簡単に計算でき、特定のしきい値に基づいてPASSEDまたはFAILEDを返すこともできます (何らかの理由で「ゼロの赤」が必ずしも必要でない場合)。
PDF をビットマップ (または少なくとも可逆圧縮) 画像としてキャプチャし、各テストによって生成された画像を、本来の外観の参照画像と比較することができます。違いがあると、テストのエラーとしてフラグが立てられます。
私の頭に浮かぶ最初のアイデアは、diffユーティリティを使用することです。これらは通常、ドキュメントのテキストを比較するために使用されますが、PDFのレイアウトを比較する場合もあります。これを使用して、期待される出力を提供される出力と比較できます。
グーグルが私に与える最初の結果はこれです。商用ですが、他のフリー/オープンソースの選択肢があるかもしれません。
xpresserを使用してこれを試してみます-(https://wiki.ubuntu.com/Xpresser)画像を正確なコピーではなく類似の画像に一致させることができます-これらの場合の問題です。
xpresser が積極的に開発されているのか、それともスタンドアローンの画像ファイルで使用できるのかはわかりません (私はそう思います)。 xpresser は Python です)。
雇用主のドキュメントの PDF を検証するツールを Python で作成しました。個々のページをマスター イメージと比較する機能があります。swftoolsという名前のライブラリを使用してページを PNG にエクスポートし、次にPython Imaging Libraryを使用してマスターと比較しました。
関連するコードは次のようになります (スクリプトの他の部分にいくつかの依存関係があるため、これは実行されませんが、アイデアを得る必要があります)。
# exporting
gfxpdf = gfx.open("pdf", self.pdfpath)
if os.path.isfile(pngPath):
os.remove(pngPath)
page = gfxpdf.getPage(pagenum)
img = gfx.ImageList()
img.startpage(page.width, page.height)
page.render(img)
img.endpage()
img.save(pngPath)
return os.path.isfile(pngPath)
# comparing
outPng = os.path.join(outpath, pngname)
masterPng = os.path.join(outpath, "_master", pngname)
if os.path.isfile(masterPng):
output = Image.open(outPng).convert("RGB") # discard alpha channel, if any
master = Image.open(masterPng).convert("RGB")
mismatch = any(x[1] for x in ImageChops.difference(output, master).getextrema())