Wie konvertiere ich ein Farb-PDF in Schwarz-Weiß?


17

Ich möchte ein PDF mit einigen farbigen Texten und Bildern in ein anderes PDF mit nur Schwarzweiß umwandeln, um die Abmessungen zu verringern. Außerdem möchte ich den Text als Text behalten, ohne die Seitenelemente in Bilder umzuwandeln. Ich habe den folgenden Befehl ausprobiert:

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

in einer anderen frage einen link gefunden , der aber macht was ich nicht will: der text in der ausgabe wird in ein schlechtes bild umgewandelt und ist nicht mehr auswählbar. Ich habe es mit Ghostscript versucht:

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

es gibt mir aber folgende fehlermeldung:

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

Gibt es eine andere Möglichkeit, die Datei zu erstellen?




Vorsicht bei der Verwendung einiger Superuser-Ansätze: Sie konvertieren die PDF-Datei in eine gerasterte Version, sodass keine Vektorgrafiken mehr angezeigt werden.
slm

1
Ist das das gesamte Skript, das Sie ausgeführt haben? Es sieht nicht so aus, könntest du das ganze Skript posten?
terdon

Antworten:


22

Das gs Beispiel

Der gsBefehl, den Sie oben ausführen, hat einen Trailing, $1der normalerweise zum Übergeben von Befehlszeilenargumenten an ein Skript gedacht ist. Ich bin mir also nicht sicher, was Sie tatsächlich versucht haben, aber ich vermute, dass Sie versucht haben, diesen Befehl in ein Skript zu schreiben 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

Und führe es so aus:

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

Nicht sicher, wie Sie dieses Skript einrichten, aber es muss ausführbar sein.

$ chmod +x script.sh

Irgendetwas scheint mit diesem Skript definitiv nicht in Ordnung zu sein. Als ich es versuchte, bekam ich stattdessen diesen Fehler:

Nicht behebbarer Fehler: Bereichsprüfung in .putdeviceprops

Eine Alternative

Anstelle dieses Skripts würde ich stattdessen dieses aus der SU-Frage verwenden.

#!/bin/bash

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

Dann führe es so aus:

$ ./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

Du hast recht, mit dem Skript stimmt etwas nicht: "Etwas" wäre in diesem Fall das, sProcessColorModelwas dProcessColorModelstattdessen sein sollte .
Sora.

8

Ich habe hier ein Skript gefunden , das das kann. Es setzt gsaber auch voraus, was Sie zu haben scheinen pdftk. Sie haben Ihre Distribution nicht erwähnt, aber auf Debian-basierten Systemen sollten Sie in der Lage sein, sie mit zu installieren

sudo apt-get install pdftk

Sie können RPMs für sie finden hier .

pdftkSpeichern Sie das Skript nach der Installation unter graypdf.shund führen Sie es folgendermaßen aus:

./greypdf.sh input.pdf

Es wird eine Datei mit dem Namen erstellt input-gray.pdf. Ich füge das ganze Skript hier ein, um einen "Link Rot" zu vermeiden:

# 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). 

3

Ich hatte auch einige gescannte Farb-PDFs und Graustufen-PDFs, die ich in SW konvertieren wollte. Ich habe versucht mitgs mit dem hier aufgeführten Code zu arbeiten , und die Bildqualität ist gut, wenn der PDF-Text noch vorhanden ist. Dieser gs-Code konvertiert jedoch nur in Graustufen (wie in der Frage angegeben) und hat immer noch eine große Dateigröße. convertergibt sehr schlechte Ergebnisse bei direkter Verwendung.

Ich wollte bw pdfs mit guter Bildqualität und kleiner Dateigröße. Ich hätte Terdons Lösung ausprobiert, aber ich konnte pdftkmit yum (zum Zeitpunkt des Schreibens) nicht auf CentOS 7 zugreifen.

Meine Lösung verwendet gs, um Graustufen-BMP-Dateien aus dem PDF zu extrahieren,convert diese BMPs auf SW zu beschränken und sie als TIFF-Dateien zu speichern, und dann img2pdf , um die TIFF-Bilder zu komprimieren und alle zu einem PDF zusammenzuführen.

Ich habe versucht, direkt aus dem PDF zu tiff zu wechseln, aber die Qualität ist nicht die gleiche, deshalb speichere ich jede Seite in bmp. Für eine einseitige PDF-Dateiconvert es eine großartige Aufgabe, von BMP zu PDF zu wechseln. Beispiel:

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

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

gsKann bei mehreren Seiten mehrere PDF-Dateien zu einer zusammenführen, img2pdfergibt jedoch eine kleinere Dateigröße als gs. Die Tiff-Dateien müssen als Eingabe für img2pdf dekomprimiert werden. Beachten Sie, dass die zwischengeschalteten BMP- und TIFF-Dateien bei einer großen Anzahl von Seiten in der Regel groß sind. pdftkoderjoinpdf wäre besser, wenn sie komprimierte pdf-Dateien aus zusammenführen können convert.

Ich stelle mir vor, es gibt eine elegantere Lösung. Meine Methode liefert jedoch Ergebnisse mit einer sehr guten Bildqualität und einer viel kleineren Dateigröße. Führen Sie OCR erneut aus, um den Text wieder in das bw-PDF zu laden.

Mein Shell-Skript verwendet gs, convert und img2pdf. Ändern Sie die am Anfang aufgeführten Parameter (Anzahl der Seiten, Scan-dpi, Schwellenwert% usw.) nach Bedarf und führen Sie sie aus chmod +x ./pdf2bw.sh. Hier ist das vollständige Skript (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

1

RHEL6 und RHEL5, die beide Ghostscript auf 8.70 basierten, konnten die oben angegebenen Befehlsformen nicht verwenden. Unter der Annahme, dass ein Skript oder eine Funktion die PDF-Datei als erstes Argument "$ 1" erwartet, sollte Folgendes portabler sein:

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

Wobei der Ausgabedatei "grey_" vorangestellt wird.

RHEL6 und 5 können CompatibilityLevel = 1.4 verwenden, was viel schneller ist, aber ich habe Portabilität angestrebt.


Entwickler sagen ( 1 , 2 , 3 , 4 ), dass es keinen sColorConversionStrategyForImagesSchalter gibt.
Igor

Danke, @Igor - Ich habe keine Ahnung, woher ich diesen Ausschnitt habe! Ich weiß, dass ich es getestet habe und es zu der Zeit funktionierte . (Und deshalb, Leute, sollten Sie immer Referenzen für Ihren Code
Rich

1
Dieser "gefälschte Parameter" scheint im Web unglaublich beliebt zu sein. GS ignoriert unbekannte Schalter (was traurig ist), so dass es trotzdem funktioniert.
Igor

1

Ich erhalte zuverlässige Ergebnisse bei der Bereinigung gescannter PDFs, die im Gegensatz zu diesem Skript stehen.

#!/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*
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.