Comment convertir un pdf couleur en noir-blanc?


18

Je voudrais transformer un pdf avec du texte et des images en couleur en un autre pdf avec seulement du noir et blanc, afin de réduire ses dimensions. De plus, je voudrais garder le texte en tant que texte, sans transformer les éléments des pages en images. J'ai essayé la commande suivante:

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

trouvé dans une autre question, un lien , mais il fait ce que je ne veux pas: le texte dans la sortie est transformé en une mauvaise image et n'est plus sélectionnable. J'ai essayé avec 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

mais cela me donne le message d'erreur suivant:

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

Existe-t-il un autre moyen de créer le fichier?




Attention, lorsque vous utilisez certaines des approches de superutilisateur, elles convertissent le PDF en une version pixellisée, il ne s'agit donc plus de graphiques vectoriels.
slm

1
Est-ce l'intégralité du script que vous avez exécuté? Cela ne ressemble pas à ça, pourriez-vous publier le script en entier?
terdon

Réponses:


23

L'exemple gs

La gscommande que vous exécutez ci-dessus a une fin $1qui est généralement destinée à passer des arguments de ligne de commande dans un script. Je ne suis donc pas sûr de ce que vous avez réellement essayé, mais je suppose que vous avez essayé de mettre cette commande dans un script 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

Et lancez-le comme ceci:

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

Je ne sais pas comment vous avez configuré ce script, mais il doit être exécutable.

$ chmod +x script.sh

Cependant, quelque chose ne semble pas correct avec ce script. Quand je l'ai essayé, j'ai eu cette erreur à la place:

Erreur irrécupérable: vérification de la portée dans .putdeviceprops

Une alternative

Au lieu de ce script, j'utiliserais plutôt celui de la question SU.

#!/bin/bash

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

Ensuite, exécutez-le comme ceci:

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

Vous avez raison, il y a quelque chose qui ne va pas avec le script: "quelque chose" dans ce cas serait ce sProcessColorModelqui devrait être à la dProcessColorModelplace.
Sora.

8

J'ai trouvé un script ici qui peut le faire. Cela nécessite gsce que vous semblez avoir mais aussi pdftk. Vous n'avez pas mentionné votre distribution mais sur les systèmes basés sur Debian, vous devriez pouvoir l'installer avec

sudo apt-get install pdftk

Vous pouvez trouver des RPM pour cela ici .

Une fois que vous avez installé pdftk, enregistrez le script sous graypdf.shet exécutez comme suit:

./greypdf.sh input.pdf

Il créera un fichier appelé input-gray.pdf. J'inclus tout le script ici pour éviter la pourriture des liens:

# 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

J'avais également des fichiers PDF couleur numérisés et des fichiers PDF en niveaux de gris que je voulais convertir en bw. J'ai essayé d'utiliser gsavec le code répertorié ici , et la qualité d'image est bonne avec du texte pdf toujours là. Cependant, ce code gs se convertit uniquement en niveaux de gris (comme demandé dans la question) et a toujours une grande taille de fichier. convertdonne de très mauvais résultats lorsqu'il est utilisé directement.

Je voulais des pdfs bw avec une bonne qualité d'image et une petite taille de fichier. J'aurais essayé la solution de terdon, mais je n'ai pas pu utiliser pdftkcentOS 7 en utilisant yum (au moment de la rédaction).

Ma solution utilise gspour extraire les fichiers bmp en niveaux de gris du pdf, convertpour seuiller ces bmps pour bw et les enregistrer en tant que fichiers tiff, puis img2pdf pour compresser les images tiff et les fusionner toutes dans un pdf.

J'ai essayé d'aller directement au tiff depuis le pdf mais la qualité n'est pas la même donc j'enregistre chaque page en bmp. Pour un fichier pdf d'une page, convertfait un excellent travail de bmp en pdf. Exemple:

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

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

Pour plusieurs pages, gspeut fusionner plusieurs fichiers pdf en un seul, mais img2pdfdonne une taille de fichier plus petite que gs. Les fichiers tiff doivent être décompressés en entrée dans img2pdf. Gardez à l'esprit pour un grand nombre de pages, les fichiers bmp et tiff intermédiaires ont tendance à être de grande taille. pdftkou joinpdfserait mieux s'ils peuvent fusionner des fichiers pdf compressés à partir de convert.

J'imagine qu'il existe une solution plus élégante. Cependant, ma méthode produit des résultats avec une très bonne qualité d'image et une taille de fichier beaucoup plus petite. Pour récupérer le texte dans le pdf bw, réexécutez l'OCR.

Mon script shell utilise gs, convert et img2pdf. Modifiez les paramètres (nombre de pages, numérisation dpi, seuil%, etc.) répertoriés au début si nécessaire et exécutez chmod +x ./pdf2bw.sh. Voici le script complet (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 et RHEL5, qui utilisent tous les deux Ghostscript sur 8.70, n'ont pas pu utiliser les formes de la commande ci-dessus. En supposant un script ou une fonction attendant le fichier PDF comme premier argument "$ 1", ce qui suit devrait être plus portable:

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

Où le fichier de sortie sera préfixé avec "grey_".

RHEL6 et 5 peuvent utiliser CompatibilityLevel = 1.4, ce qui est beaucoup plus rapide, mais je visais la portabilité.


Les développeurs disent ( 1 , 2 , 3 , 4 ) qu'il n'y a pas de sColorConversionStrategyForImagescommutateur.
Igor

Merci, @Igor - Je n'ai aucune idée d'où j'ai obtenu cet extrait! Je sais pertinemment que je l'ai testé et cela a fonctionné à l'époque . (Et c'est pour cela que vous devriez toujours fournir des références pour votre code.)
Rich

1
Ce "faux paramètre" semble être incroyablement populaire sur le Web. GS ignore les commutateurs inconnus (ce qui est triste), donc cela fonctionne quand même.
Igor

1

J'obtiens des résultats fiables en nettoyant les PDF scannés pour un bon contraste avec ce script;

#!/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*
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.