web-dev-qa-db-ja.com

PDFファイルをグレースケールから白黒に変換するにはどうすればよいですか?

私のOSはUbuntu 12.04です。 PDFファイルをグレースケールから白黒に変換するにはどうすればよいですか?グレースケールpdfファイルは、グレースケールオプションでスキャンしたもので、OCRでは白黒スケールpdfが必要です。


更新:

マルコの返答に続き、 the B-W pdf は良くなく、元のファイルは here です。

11
Tim

1) ghostscript を使用して、PDFをpsmonoを使用してモノクロPostScriptファイルに変換します)端末:

gs -q -sDEVICE=psmono -o mono.ps input.pdf

2)次に、モノクロPostScriptをPDFに変換します。

ps2pdf mono.ps

EDIT:psmonoデバイスは1ビットのハーフトーンイメージを作成しますが、これは明らかに希望どおりのものではありません。 ghostscriptを使用してしきい値を指定する方法が見つからなかったため、imagemagickを使用しました。 convertは内部的にghostscriptを使用してPDFを変換します。次に、しきい値フィルタリングを適用して1ビット画像を作成し、再度ghostscriptを使用してPDFを作成します。 convertはデフォルトで75DPIの解像度を使用するため、実際の解像度と一致しない場合があるため、density引数を指定できます。そして、threshold設定を試してください。最適値は、入力ファイルに大きく依存します。

convert -density 150 -threshold 50% input.pdf output.pdf
9
Marco

私が見つけた最良の方法は、品質を損なうことなく、次のページからにじみ出る影、ノイズ、テキストを削除します。

1)まずpdfを個別の画像に変換します

pdfimages combined_ocr.pdf page

2)次に、次のページから流れ出る影、ノイズ、テキストを削除します(クレジット このブログへ

ls ./p*.ppm | xargs -L1 -I {} convert {}  -quality 100 -density 300 -fill white -fuzz 80% +opaque "#000000" {}.jpg

これを追加のステップとして、または上記のコマンドの代わりに追加して、実際に2色のみを取得できます。

ls ./p*.ppm | xargs -L1 -I {} convert {} +dither -colors 2 -type bilevel -density 300 -fill white -fuzz 40% +opaque "#000000" -density 300 {}.jpg

3)これは、解像度や品質を損なうことなく、すべてのjpg画像からpdfファイルを作成するためのものです。

ls -1 ./*jpg | xargs -L1 -I {} img2pdf {} -o {}.pdf

4)これは、PDFページを1つに連結するためのものです。

pdftk *.pdf cat output combined.pdf

5)そして最後に、PDFのスキャンの品質を変更しないOCRedテキストレイヤーを追加して、検索可能にします。

pypdfocr combined.pdf 
4

また、bwに変換したいスキャンされたカラーPDFとグレースケールPDFもいくつか持っていました。 gsここにリストされているコード と一緒に使用してみましたが、PDFテキストがあるため画質は良好です。ただし、そのgsコードは(質問で尋ねられたように)グレースケールにのみ変換され、ファイルサイズはまだ大きくなります。 convertを直接使用すると、結果が非​​常に悪くなります。

良い画像品質と小さなファイルサイズのbw pdfが必要でした。私の解決策は、gsを使用してPDFからグレースケールbmpファイルを抽出し、convertを使用してそれらのbmpをbwにしきい値処理してtiffファイルとして保存し、次に img2pdf を使用して画像をtiffし、それらをすべて1つのPDFにマージします。

私は直接PDFからtiffに行ってみましたが、品質は同じではないので、各ページをbmpに保存します。 1ページのpdfファイルの場合、convertはbmpからpdfまで素晴らしい働きをします。例:

gs -sDEVICE=bmpgray -dNOPAUSE -dBATCH -r300x300 \
   -sOutputFile=./pdf_image.bmp ./input.pdf

convert ./pdf_image.bmp -threshold 40% -compress Zip ./bw_out.pdf

複数のページの場合、gsは複数のPDFファイルを1つにマージできますが、img2pdfは、gsよりもファイルサイズが小さくなります。 tiffファイルは、img2pdfへの入力として圧縮解除する必要があります。ページ数が多い場合は、中間のbmpおよびtiffファイルのサイズが大きくなる傾向があることに注意してください。 pdftkからの圧縮PDFファイルをマージできる場合は、joinpdfまたはconvertの方が適しています。

もっとエレガントな解決策があると思います。ただし、私の方法では、非常に良好な画質とはるかに小さいファイルサイズで結果が生成されます。テキストをbw pdfに戻すには、OCRを再度実行します。

私のシェルスクリプトでは、gs、convert、img2pdfを使用しています。最初にリストされているパラメーター(ページ数、スキャンdpi、しきい値%など)を必要に応じて変更し、chmod +x ./pdf2bw.sh。完全なスクリプト(pdf2bw.sh)は次のとおりです。

#!/bin/bash

num_pages=12
dpi_res=300
input_pdf_name=color_or_grayscale.pdf
bw_threshold=40%
output_pdf_name=out_bw.pdf
#-------------------------------------------------------------------------
gs -sDEVICE=bmpgray -dNOPAUSE -dBATCH -q -r$dpi_res \
   -sOutputFile=./%d.bmp ./$input_pdf_name
#-------------------------------------------------------------------------
for file_num in `seq 1 $num_pages`
do
  convert ./$file_num.bmp -threshold $bw_threshold \
          ./$file_num.tif
done
#-------------------------------------------------------------------------
input_files=""

for file_num in `seq 1 $num_pages`
do
  input_files+="./$file_num.tif "
done

img2pdf -o ./$output_pdf_name --dpi $dpi_res $input_files
#-------------------------------------------------------------------------
# clean up bmp and tif files used in conversion

for file_num in `seq 1 $num_pages`
do
  rm ./$file_num.bmp
  rm ./$file_num.tif
done
3
OccamsRazor

実際、それがスキャンからのものである場合、唯一の妥当な方法は、pdfimagesを使用して、基になるグラフィックを変換することです。このスクリプトを使用して変換しました。

#!/bin/sh
if [ -z "$1" -o -z "$2" ]; then
    echo "Syntax: $0 <input.pdf> <output.pdf>"
    exit 1
fi

pdfimages "$1" scan
for a in scan*.ppm; do 
   convert -white-threshold 85% -monochrome $a `basename $a .ppm`.tiff
done
tiffcp scan*.tiff output.tiff
tiff2pdf output.tiff -o "$2" -p A4 -F
rm scan*.ppm scan*.tiff output.tiff
2
ondra

OccamsRazorのスクリプトをありがとう。このスクリプトは、カラーPDFとグレースケールPDFの両方をコンパクトで読みやすいモノクロバージョンに変換する優れた機能を果たします。これは本当にOccamsRazorの投稿へのコメントですが、コメントするのに十分なポイントがありません。

img2pdf -o ./$output_pdf_name --dpi $dpi_res $input_filesはimg2pdfの引数として受け入れられなくなったため、スクリプトは--dpiで失敗します。代わりに、入力ファイルから解像度を取得するので、そのままにしておくことができます。

これが私のスクリプトのバージョンです。すべてのファイルのスクリプトを編集したくなかったので、実行時にページ数と入力ファイル名を渡しました。出力名を00input_nameに設定し、解像度を200 dpiに設定しました。これは私のワークフローで機能しますが、変更するか、それらを$3および$4に変換して渡すこともできます。それらの。

実行するには、./pdf2bw.sh <number_of_pages><input_name>を使用します(例:./pdf2bw.sh 55 input.pdf)。

#!/bin/bash

num_pages=$1
input_pdf_name=$2
output_pdf_name="00$2"
bw_threshold=40%
dpi_res=200
#-------------------------------------------------------------------------
gs -sDEVICE=bmpgray -dNOPAUSE -dBATCH -q -r$dpi_res \
   -sOutputFile=./%d.bmp ./$input_pdf_name
#-------------------------------------------------------------------------
for file_num in `seq 1 $num_pages`
do
  convert ./$file_num.bmp -threshold $bw_threshold \
          ./$file_num.tif
done
#-------------------------------------------------------------------------
input_files=""

for file_num in `seq 1 $num_pages`
do
  input_files+="./$file_num.tif "
done

img2pdf -o ./$output_pdf_name $input_files
#-------------------------------------------------------------------------
# clean up bmp and tif files used in conversion

for file_num in `seq 1 $num_pages`
do
  rm ./$file_num.bmp
  rm ./$file_num.tif
done
2
lowwall