Bagaimana cara mengubah pdf warna menjadi hitam-putih?

18

Saya ingin mengubah pdf dengan beberapa teks berwarna dan gambar dalam pdf lain dengan hanya hitam & putih, untuk mengurangi dimensinya. Selain itu, saya ingin menjaga teks sebagai teks, tanpa mengubah elemen halaman dalam gambar. Saya mencoba perintah berikut:

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

ditemukan dalam pertanyaan lain, sebuah tautan , tetapi ia melakukan apa yang tidak saya inginkan: teks dalam output ditransformasikan dalam gambar yang buruk dan tidak lagi dapat dipilih. Saya mencoba dengan 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

tapi itu memberi saya pesan kesalahan berikut:

./script.sh: 19: ./script.sh: output.pdf: not found

Apakah ada cara lain untuk membuat file?

BowPark
sumber
Ini terlihat sangat bagus superuser.com/questions/200378/…
slackmart
Perhatian saat menggunakan beberapa pendekatan superuser, mereka mengkonversi PDF ke versi raster, jadi itu bukan lagi vektor grafis.
slm
1
Apakah itu keseluruhan skrip yang Anda jalankan? Tidak terlihat seperti itu, bisakah Anda memposting seluruh skrip?
terdon

Jawaban:

23

Contoh gs

The gsperintah Anda menjalankan di atas memiliki trailing $1yang biasanya dimaksudkan untuk melewati argumen baris perintah ke script. Jadi aku tidak yakin apa yang Anda benar-benar mencoba tapi aku menebak bahwa Anda mencoba untuk menempatkan perintah yang menjadi naskah, 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

Dan jalankan seperti ini:

$ ./script.sh: 19: ./script.sh: output.pdf: not found

Tidak yakin bagaimana Anda mengatur skrip ini tetapi harus dapat dieksekusi.

$ chmod +x script.sh

Sesuatu yang sepertinya tidak beres dengan naskah itu. Ketika saya mencobanya saya malah mendapatkan kesalahan ini:

Kesalahan yang tidak dapat dipulihkan: rangecheck di .putdeviceprops

Sebuah alternatif

Alih-alih script yang saya gunakan ini dari pertanyaan SU sebagai gantinya.

#!/bin/bash

gs \
 -sOutputFile=output.pdf \
 -sDEVICE=pdfwrite \
 -sColorConversionStrategy=Gray \
 -dProcessColorModel=/DeviceGray \
 -dCompatibilityLevel=1.4 \
 -dNOPAUSE \
 -dBATCH \
 $1

Kemudian jalankan seperti ini:

$ ./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
slm
sumber
Anda benar, ada yang salah dengan skrip: "sesuatu" dalam hal ini sProcessColorModelyang seharusnya dProcessColorModel.
Sora.
8

Saya menemukan skrip di sini yang dapat melakukan ini. Ini membutuhkan gsyang tampaknya Anda miliki tetapi juga pdftk. Anda belum menyebutkan distribusi Anda tetapi pada sistem berbasis Debian, Anda harus dapat menginstalnya

sudo apt-get install pdftk

Anda dapat menemukan RPM di sini .

Setelah Anda menginstal pdftk, simpan skrip sebagai graypdf.shdan jalankan seperti:

./greypdf.sh input.pdf

Ini akan membuat file bernama input-gray.pdf. Saya menyertakan seluruh skrip di sini untuk menghindari tautan busuk:

# 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). 
terdon
sumber
3

Saya juga memiliki beberapa pdf warna yang dipindai dan pdf abu-abu yang ingin saya konversi menjadi bw. Saya mencoba menggunakan gsdengan kode yang tercantum di sini , dan kualitas gambar bagus dengan teks pdf masih ada. Namun, kode gs itu hanya mengkonversi ke skala abu-abu (seperti yang ditanyakan dalam pertanyaan) dan masih memiliki ukuran file yang besar. convertmenghasilkan hasil yang sangat buruk bila digunakan secara langsung.

Saya ingin pw bw dengan kualitas gambar bagus dan ukuran file kecil. Saya akan mencoba solusi terdon, tetapi saya tidak bisa pdftkmenggunakan centOS 7 menggunakan yum (pada saat penulisan).

Solusi saya gunakan gsuntuk mengekstrak file bmp skala abu-abu dari pdf, convertuntuk membatasi bmps menjadi bw dan menyimpannya sebagai file tiff, dan kemudian img2pdf untuk mengompres gambar tiff dan menggabungkan semuanya menjadi satu pdf.

Saya mencoba langsung tiff dari pdf tapi kualitasnya tidak sama jadi saya menyimpan setiap halaman ke bmp. Untuk file pdf satu halaman, convertlakukan pekerjaan yang hebat dari bmp ke pdf. Contoh:

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

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

Untuk beberapa halaman, gsdapat menggabungkan beberapa file pdf menjadi satu, tetapi img2pdfmenghasilkan ukuran file yang lebih kecil daripada gs. File tiff harus dikompresi sebagai input ke img2pdf. Ingatlah untuk halaman dalam jumlah besar, file bmp dan tiff menengah cenderung berukuran besar. pdftkatau joinpdfakan lebih baik jika mereka dapat menggabungkan file pdf terkompresi dari convert.

Saya membayangkan ada solusi yang lebih elegan. Namun, metode saya menghasilkan hasil dengan kualitas gambar yang sangat baik dan ukuran file yang jauh lebih kecil. Untuk mendapatkan kembali teks dalam bw pdf, jalankan OCR lagi.

Script shell saya menggunakan gs, convert, dan img2pdf. Ubah parameter (# halaman, pindai dpi, ambang batas%, dll) yang tercantum di awal sesuai kebutuhan, dan jalankan chmod +x ./pdf2bw.sh. Berikut ini skrip lengkap (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
Pisau cukur Occam
sumber
1

RHEL6 dan RHEL5, yang keduanya merupakan baseline Ghostscript pada 8.70, tidak dapat menggunakan bentuk-bentuk perintah yang diberikan di atas. Dengan asumsi skrip atau fungsi yang mengharapkan file PDF sebagai argumen pertama "$ 1", berikut ini harus lebih portabel:

gs \
    -sOutputFile="grey_$1" \
    -sDEVICE=pdfwrite \
    -sColorConversionStrategy=Mono \
    -sColorConversionStrategyForImages=/Mono \
    -dProcessColorModel=/DeviceGray \
    -dCompatibilityLevel=1.3 \
    -dNOPAUSE -dBATCH \
    "$1"

Di mana file output akan diawali dengan "grey_".

RHEL6 dan 5 dapat menggunakan CompatibilityLevel = 1.4 yang jauh lebih cepat, tetapi saya bertujuan untuk portabilitas.

Kaya
sumber
Devs mengatakan ( 1 , 2 , 3 , 4 ) bahwa tidak ada sColorConversionStrategyForImagessaklar.
Igor
Terima kasih, @Igor - Saya tidak tahu dari mana saya mendapatkan cuplikan itu! Saya tahu benar bahwa saya mengujinya dan itu bekerja pada saat itu . (Dan itu, kawan-kawan, itulah sebabnya Anda harus selalu memberikan referensi untuk kode Anda.)
Rich
1
"Parameter palsu" itu tampaknya sangat populer di kalangan web. GS mengabaikan switch yang tidak dikenal (yang menyedihkan), jadi itu tetap bekerja.
Igor
1

Saya mendapatkan hasil yang andal membersihkan pdf yang dipindai agar kontras dengan skrip ini;

#!/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*
Bijou Smith
sumber