サイズを小さくするために、いくつかのカラーのテキストと画像を含むPDFを、白黒のみの別のPDFに変換したいと思います。さらに、画像のページ要素を変換せずに、テキストをテキストとして保持したいと考えています。私は次のコマンドを試しました:
convert -density 150 -threshold 50% input.pdf output.pdf
別の質問 a link で見つかりましたが、それは私が望んでいないことを行います。出力のテキストが不適切な画像に変換され、選択できなくなります。私はGhostscriptで試しました:
gs -sOutputFile=output.pdf \
-q -dNOPAUSE -dBATCH -dSAFER \
-sDEVICE=pdfwrite \
-dCompatibilityLevel=1.3 \
-dPDFSETTINGS=/screen \
-dEmbedAllFonts=true \
-dSubsetFonts=true \
-sColorConversionStrategy=/Mono \
-sColorConversionStrategyForImages=/Mono \
-sProcessColorModel=/DeviceGray \
$1
しかし、次のエラーメッセージが表示されます。
./script.sh: 19: ./script.sh: output.pdf: not found
ファイルを作成する他の方法はありますか?
上で実行しているgs
コマンドには、末尾に$1
これは通常、コマンドライン引数をスクリプトに渡すためのものです。そのため、実際に何を試したのかはわかりませんが、そのコマンドをスクリプトに入れようとしたと思います。script.sh
:
#!/bin/bash
gs -sOutputFile=output.pdf \
-q -dNOPAUSE -dBATCH -dSAFER \
-sDEVICE=pdfwrite \
-dCompatibilityLevel=1.3 \
-dPDFSETTINGS=/screen \
-dEmbedAllFonts=true \
-dSubsetFonts=true \
-sColorConversionStrategy=/Mono \
-sColorConversionStrategyForImages=/Mono \
-sProcessColorModel=/DeviceGray \
$1
そして、次のように実行します。
$ ./script.sh: 19: ./script.sh: output.pdf: not found
このスクリプトの設定方法はわかりませんが、実行可能にする必要があります。
$ chmod +x script.sh
しかし、そのスクリプトでは間違いなく何かが正しくないようです。試してみたところ、代わりに次のエラーが発生しました。
回復不能なエラー:.putdevicepropsの範囲チェック
そのスクリプトの代わりに、SUの質問からこれを使用します。
#!/bin/bash
gs \
-sOutputFile=output.pdf \
-sDEVICE=pdfwrite \
-sColorConversionStrategy=Gray \
-dProcessColorModel=/DeviceGray \
-dCompatibilityLevel=1.4 \
-dNOPAUSE \
-dBATCH \
$1
次に、次のように実行します。
$ ./script.bash LeaseContract.pdf
GPL Ghostscript 8.71 (2010-02-10)
Copyright (C) 2010 Artifex Software, Inc. All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 2.
Page 1
Page 2
これを実行できるスクリプト here を見つけました。 gs
が必要ですが、 pdftk
も必要です。ディストリビューションについては言及していませんが、Debianベースのシステムでは、次のコマンドでインストールできます。
Sudo apt-get install pdftk
あなたはそれのためのRPMを見つけることができます ここ 。
pdftk
をインストールしたら、スクリプトをgraypdf.sh
として保存し、次のように実行します。
./greypdf.sh input.pdf
input-gray.pdf
というファイルが作成されます。リンクの腐敗を防ぐために、スクリプト全体をここに含めています。
# convert pdf to grayscale, preserving metadata
# "AFAIK graphicx has no feature for manipulating colorspaces. " http://groups.google.com/group/latexusersgroup/browse_thread/thread/5ebbc3ff9978af05
# "> Is there an easy (or just standard) way with pdflatex to do a > conversion from color to grayscale when a PDF file is generated? No." ... "If you want to convert a multipage document then you better have pdftops from the xpdf suite installed because Ghostscript's pdf to ps doesn't produce Nice Postscript." http://osdir.com/ml/tex.pdftex/2008-05/msg00006.html
# "Converting a color EPS to grayscale" - http://en.wikibooks.org/wiki/LaTeX/Importing_Graphics
# "\usepackage[monochrome]{color} .. I don't know of a neat automatic conversion to monochrome (there might be such a thing) although there was something in Tugboat a while back about mapping colors on the fly. I would probably make monochrome versions of the pictures, and name them consistently. Then conditionally load each one" http://newsgroups.derkeiler.com/Archive/Comp/comp.text.tex/2005-08/msg01864.html
# "Here comes optional.sty. By adding \usepackage{optional} ... \opt{color}{\includegraphics[width=0.4\textwidth]{intro/benzoCompounds_color}} \opt{grayscale}{\includegraphics[width=0.4\textwidth]{intro/benzoCompounds}} " - http://chem-bla-ics.blogspot.com/2008/01/my-phd-thesis-in-color-and-grayscale.html
# with gs:
# http://handyfloss.net/2008.09/making-a-pdf-grayscale-with-ghostscript/
# note - this strips metadata! so:
# http://etutorials.org/Linux+systems/pdf+hacks/Chapter+5.+Manipulating+PDF+Files/Hack+64+Get+and+Set+PDF+Metadata/
COLORFILENAME=$1
OVERWRITE=$2
FNAME=${COLORFILENAME%.pdf}
# NOTE: pdftk does not work with logical page numbers / pagination;
# gs kills it as well;
# so check for existence of 'pdfmarks' file in calling dir;
# if there, use it to correct gs logical pagination
# for example, see
# http://askubuntu.com/questions/32048/renumber-pages-of-a-pdf/65894#65894
PDFMARKS=
if [ -e pdfmarks ] ; then
PDFMARKS="pdfmarks"
echo "$PDFMARKS exists, using..."
# convert to gray pdf - this strips metadata!
gs -sOutputFile=$FNAME-gs-gray.pdf -sDEVICE=pdfwrite \
-sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray \
-dCompatibilityLevel=1.4 -dNOPAUSE -dBATCH "$COLORFILENAME" "$PDFMARKS"
else # not really needed ?!
gs -sOutputFile=$FNAME-gs-gray.pdf -sDEVICE=pdfwrite \
-sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray \
-dCompatibilityLevel=1.4 -dNOPAUSE -dBATCH "$COLORFILENAME"
fi
# dump metadata from original color pdf
## pdftk $COLORFILENAME dump_data output $FNAME.data.txt
# also: pdfinfo -meta $COLORFILENAME
# grep to avoid BookmarkTitle/Level/PageNumber:
pdftk $COLORFILENAME dump_data output | grep 'Info\|Pdf' > $FNAME.data.txt
# "pdftk can take a plain-text file of these same key/value pairs and update a PDF's Info dictionary to match. Currently, it does not update the PDF's XMP stream."
pdftk $FNAME-gs-gray.pdf update_info $FNAME.data.txt output $FNAME-gray.pdf
# (http://wiki.creativecommons.org/XMP_Implementations : Exempi ... allows reading/writing XMP metadata for various file formats, including PDF ... )
# clean up
rm $FNAME-gs-gray.pdf
rm $FNAME.data.txt
if [ "$OVERWRITE" == "y" ] ; then
echo "Overwriting $COLORFILENAME..."
mv $FNAME-gray.pdf $COLORFILENAME
fi
# BUT NOTE:
# Mixing TEX & PostScript : The GEX Model - http://www.tug.org/TUGboat/Articles/tb21-3/tb68kost.pdf
# VTEX is a (commercial) extended version of TEX, sold by MicroPress, Inc. Free versions of VTEX have recently been made available, that work under OS/2 and Linux. This paper describes GEX, a fast fully-integrated PostScript interpreter which functions as part of the VTEX code-generator. Unless specified otherwise, this article describes the functionality in the free- ware version of the VTEX compiler, as available on CTAN sites in systems/vtex.
# GEX is a graphics counterpart to TEX. .. Since GEX may exercise subtle influence on TEX (load fonts, or change TEX registers), GEX is op- tional in VTEX implementations: the default oper- ation of the program is with GEX off; it is enabled by a command-line switch.
# \includegraphics[width=1.3in, colorspace=grayscale 256]{macaw.jpg}
# http://mail.tug.org/texlive/Contents/live/texmf-dist/doc/generic/FAQ-en/html/FAQ-TeXsystems.html
# A free version of the commercial VTeX extended TeX system is available for use under Linux, which among other things specialises in direct production of PDF from (La)TeX input. Sadly, it���s no longer supported, and the ready-built images are made for use with a rather ancient Linux kernel.
# NOTE: another way to capture metadata; if converting via ghostscript:
# http://compgroups.net/comp.text.pdf/How-to-specify-metadata-using-Ghostscript
# first:
# grep -a 'Keywo' orig.pdf
# /Author(xxx)/Title(ttt)/Subject()/Creator(LaTeX)/Producer(pdfTeX-1.40.12)/Keywords(kkkk)
# then - copy this data in a file prologue.ini:
#/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
#[/Author(xxx)
#/Title(ttt)
#/Subject()
#/Creator(LaTeX with hyperref package + gs w/ prologue)
#/Producer(pdfTeX-1.40.12)
#/Keywords(kkkk)
#/DOCINFO pdfmark
#
# finally, call gs on the orig file,
# asking to process pdfmarks in prologue.ini:
# gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 \
# -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -dBATCH -dDOPDFMARKS \
# -sOutputFile=out.pdf in.pdf prologue.ini
# then the metadata will be in output too (which is stripped otherwise;
# note bookmarks are preserved, however).
また、bwに変換したいスキャンされたカラーPDFとグレースケールPDFもいくつか持っていました。 gs
を ここにリストされているコード と一緒に使用してみましたが、PDFテキストが残っているため、画質は良好です。ただし、そのgsコードは(質問で尋ねられたように)グレースケールに変換されるだけで、ファイルサイズが大きくなります。 convert
を直接使用すると、結果が非常に悪くなります。
良い画像品質と小さなファイルサイズのbw pdfが欲しかった。 terdonの解決策を試しましたが、(執筆時点で)yumを使用してcentOS 7でpdftk
を取得できませんでした。
私のソリューションは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
スキャンしたPDFをこのスクリプトと対照的にクリーンアップして、信頼できる結果を得ました。
#!/bin/bash
#
# $ Sudo apt install poppler-utils img2pdf pdftk imagemagick
#
# Output is still greyscale, but lots of scanner light tone fuzz removed.
#
pdfimages $1 pages
ls ./pages*.ppm | xargs -L1 -I {} convert {} -quality 100 -density 400 \
-fill white -fuzz 80% -auto-level -depth 4 +opaque "#000000" {}.jpg
ls -1 ./pages*jpg | xargs -L1 -I {} img2pdf {} -o {}.pdf
pdftk pages*.pdf cat output ${1/.pdf/}_bw.pdf
rm pages*
8.70のベースラインGhostscriptであるRHEL6とRHEL5は、上記のコマンドの形式を使用できませんでした。最初の引数「$ 1」としてPDFファイルを想定しているスクリプトまたは関数を想定すると、以下の方が移植性が高いはずです。
gs \
-sOutputFile="grey_$1" \
-sDEVICE=pdfwrite \
-sColorConversionStrategy=Mono \
-sColorConversionStrategyForImages=/Mono \
-dProcessColorModel=/DeviceGray \
-dCompatibilityLevel=1.3 \
-dNOPAUSE -dBATCH \
"$1"
出力ファイルの先頭には「grey_」が付けられます。
RHEL6と5はCompatibilityLevel = 1.4を使用できますが、はるかに高速ですが、移植性を目指していました。
上記の多くの素晴らしい答えがあります。私は上記の答えの1つを取り、それに人間のインターフェースを追加しました。多分誰かがそれを便利だと思うでしょう。
#!/bin/bash
pdf2Gray()
{
if [ -z "$1" ]; then
return 1
else
inputFile="$1"
fi
if [ ! -f "$inputFile" ]; then
echo "File not found"
echo "$inputFile"
return 2
fi
fileType="`file -b --mime-type \"$inputFile\"`"
if [ "$fileType" != 'application/pdf' ]; then
echo "This file is not a pdf"
echo "$inputFile"
return 3
fi
outFile="`basename -s .pdf \"$inputFile\"`-gray.pdf"
if [ -f "$outFile" ]; then
echo -en "File Exists, overwrite it? (Y/n) "
read overWrite
if [ -z "$overWrite" ]; then
overWrite="y"
fi
if [[ "$overWrite" != "y" && "$overWrite" != "Y" ]]; then
return 4
fi
fi
gs \
-q \
-sOutputFile="$outFile" \
-sDEVICE=pdfwrite \
-sColorConversionStrategy=Gray \
-dProcessColorModel=/DeviceGray \
-dCompatibilityLevel=1.4 \
-dNOPAUSE \
-dBATCH \
"$inputFile"
echo -en "\033[1;32m"
echo -n "$PWD/$outFile"
echo -e "\033[0m"
}
if [ -z $1 ]; then
echo "usage:"
echo "$0 file1.pdf file2.pdf file3.pdf ..."
else
for file in "$@"
do
pdf2Gray "$file"
#echo $? #debug
done
fi