Étant donné un ensemble de fichiers PDF parmi lesquels certaines pages sont en couleur et les autres sont en noir & blanc, existe-t-il un programme pour trouver parmi les pages données qui sont en couleur et qui sont en noir & blanc? Cela serait utile, par exemple, dans l'impression d'une thèse, et seulement dépenser plus pour imprimer les pages de couleur. Des points bonus pour quelqu'un qui prend en compte l'impression recto verso, et envoie une page en noir et blanc appropriée à l'imprimante couleur si elle est suivie d'une page couleur sur le côté opposé.Comment savoir si les pages PDF sont en couleur ou en noir et blanc?
Répondre
C'est l'une des questions les plus intéressantes que j'ai vues! Je suis d'accord avec certains des autres messages qui rendent à un bitmap, puis l'analyse de l'image bitmap sera la solution la plus fiable. Pour les PDF simples, voici une approche plus rapide mais moins complète.
- Parse chaque page PDF
- Rechercher des directives de couleur (g, rg, k, sc, scn, etc.)
- Rechercher des images intégrées, d'analyser la couleur
Ma solution ci-dessous fait # 1 et la moitié de # 2. L'autre moitié de # 2 consisterait à suivre la couleur définie par l'utilisateur, ce qui implique de rechercher les entrées/ColorSpace dans la page et de les décoder - contactez-moi hors ligne si cela vous intéresse, car c'est très faisable mais pas dans 5 minutes.
D'abord le programme principal:
use CAM::PDF;
my $infile = shift;
my $pdf = CAM::PDF->new($infile);
PAGE:
for my $p (1 .. $pdf->numPages) {
my $tree = $pdf->getPageContentTree($p);
if (!$tree) {
print "Failed to parse page $p\n";
next PAGE;
}
my $colors = $tree->traverse('My::Renderer::FindColors')->{colors};
my $uncertain = 0;
for my $color (@{$colors}) {
my ($name, @rest) = @{$color};
if ($name eq 'g') {
} elsif ($name eq 'rgb') {
my ($r, $g, $b) = @rest;
if ($r != $g || $r != $b) {
print "Page $p is color\n";
next PAGE;
}
} elsif ($name eq 'cmyk') {
my ($c, $m, $y, $k) = @rest;
if ($c != 0 || $m != 0 || $y != 0) {
print "Page $p is color\n";
next PAGE;
}
} else {
$uncertain = $name;
}
}
if ($uncertain) {
print "Page $p has user-defined color ($uncertain), needs more investigation\n";
} else {
print "Page $p is grayscale\n";
}
}
Et puis est ici le moteur de rendu d'aide qui gère les directives de couleur sur chaque page:
package My::Renderer::FindColors;
sub new {
my $pkg = shift;
return bless { colors => [] }, $pkg;
}
sub clone {
my $self = shift;
my $pkg = ref $self;
return bless { colors => $self->{colors}, cs => $self->{cs}, CS => $self->{CS} }, $pkg;
}
sub rg {
my ($self, $r, $g, $b) = @_;
push @{$self->{colors}}, ['rgb', $r, $g, $b];
}
sub g {
my ($self, $gray) = @_;
push @{$self->{colors}}, ['rgb', $gray, $gray, $gray];
}
sub k {
my ($self, $c, $m, $y, $k) = @_;
push @{$self->{colors}}, ['cmyk', $c, $m, $y, $k];
}
sub cs {
my ($self, $name) = @_;
$self->{cs} = $name;
}
sub cs {
my ($self, $name) = @_;
$self->{CS} = $name;
}
sub _sc {
my ($self, $cs, @rest) = @_;
return if !$cs; # syntax error
if ($cs eq 'DeviceRGB') { $self->rg(@rest); }
elsif ($cs eq 'DeviceGray') { $self->g(@rest); }
elsif ($cs eq 'DeviceCMYK') { $self->k(@rest); }
else { push @{$self->{colors}}, [$cs, @rest]; }
}
sub sc {
my ($self, @rest) = @_;
$self->_sc($self->{cs}, @rest);
}
sub SC {
my ($self, @rest) = @_;
$self->_sc($self->{CS}, @rest);
}
sub scn { sc(@_); }
sub SCN { SC(@_); }
sub RG { rg(@_); }
sub G { g(@_); }
sub K { k(@_); }
ImageMagick dispose de méthodes intégrées de comparaison d'images.
http://www.imagemagick.org/Usage/compare/#type_general
Il existe une API Perl pour ImageMagick, alors peut-être si vous combinez intelligemment ces derniers avec un convertisseur PDF vers l'image que vous pouvez trouver un moyen de faire votre noir essai blanc &.
Je voudrais essayer de le faire comme ça, bien qu'il puisse y avoir d'autres solutions plus simples, et je suis curieux de les entendre, je veux juste donner essayer:
- boucle à travers toutes les pages
- Extraire les pages à une image
- Vérifiez la gamme de couleurs de l'image
pour le nombre de pages, vous pouvez probablement traduire that sans trop d'effort pour Perl. C'est fondamentalement une regex. Il est également said que:
r "(/ Type) \ s (/ Page) [/> \ s]?"
Il vous suffit de compter combien de fois cette expression régulière se produit dans le fichier PDF, moins les fois où vous trouver la chaîne "<>" (âges vides qui ne sont pas rendus).
Pour extraire l'image, vous pouvez utiliser ImageMagick pour faire that. Ou voir this question. Enfin, pour savoir si c'est noir et blanc, cela dépend si vous voulez dire littéralement noir et blanc ou échelle de gris. Pour le noir et blanc, vous devriez seulement, bien, noir et blanc dans toute l'image. Si vous voulez voir les niveaux de gris, maintenant, ce n'est vraiment pas ma spécialité mais je suppose que vous pouvez voir si les moyennes du rouge, du vert et du bleu sont proches ou si l'image originale et une grayscale converted sont proches de chaque autre.
Espérons que cela donne quelques conseils pour vous aider à aller plus loin.
Pour obtenir le nombre de pages: perl -le'use CAM :: PDF; print CAM :: PDF-> new ("my.pdf") -> numPages ' –
Il est possible d'utiliser l'outil Image Magickidentify
. S'il est utilisé sur des pages PDF, il convertit d'abord la page en image tramée. Si la page couleur contenue peut être testé en utilisant l'option -format "%[colorspace]"
, qui pour mon PDF a imprimé soit Gray
ou RGB
. IMHO identify
(ou quel que soit l'outil qu'il utilise en arrière-plan; Ghostscript?) Ne choisit l'espace de couleurs en fonction des cadeaux de couleur.
Un exemple est:
identify -format "%[colorspace]" $FILE.pdf[$PAGE]
où PAGE est le départ de la page de 0, pas 1. Si la sélection de page n'est pas utilisé toutes les pages sont effondrés à un, ce qui est pas ce que vous voulez.
J'ai écrit le script BASH suivant qui utilise pdfinfo
pour obtenir le nombre de pages et ensuite les boucles. Sortir les pages qui sont en couleur. J'ai également ajouté une fonction pour le document recto-verso où vous pourriez avoir besoin d'une page arrière non colorée.
Utilisation de la liste séparée de l'espace les pages en sortie PDF en couleur peuvent être extraites en utilisant pdftk
:
pdftk $FILE cat $PAGELIST output color_${FILE}.pdf
#!/bin/bash
FILE=$1
PAGES=$(pdfinfo ${FILE} | grep 'Pages:' | sed 's/Pages:\s*//')
GRAYPAGES=""
COLORPAGES=""
DOUBLECOLORPAGES=""
echo "Pages: $PAGES"
N=1
while (test "$N" -le "$PAGES")
do
COLORSPACE=$(identify -format "%[colorspace]" "$FILE[$((N-1))]")
echo "$N: $COLORSPACE"
if [[ $COLORSPACE == "Gray" ]]
then
GRAYPAGES="$GRAYPAGES $N"
else
COLORPAGES="$COLORPAGES $N"
# For double sided documents also list the page on the other side of the sheet:
if [[ $((N%2)) -eq 1 ]]
then
DOUBLECOLORPAGES="$DOUBLECOLORPAGES $N $((N+1))"
#N=$((N+1))
else
DOUBLECOLORPAGES="$DOUBLECOLORPAGES $((N-1)) $N"
fi
fi
N=$((N+1))
done
echo $DOUBLECOLORPAGES
echo $COLORPAGES
echo $GRAYPAGES
#pdftk $FILE cat $COLORPAGES output color_${FILE}.pdf
Considérons ce fichier TeX: 'hello world \ bye'. La sortie de 'identify -format"% [colorspace] "" $ FILE.pdf [0] "' est 'sRGB', alors qu'avec' gs -o - -DEDEVICE = inkcov $ FILE.pdf "' (suggéré [ici] (http://tex.stackexchange.com/a/61216/31416)) J'obtiens '0.00000 0.00000 0.00000 0.00020 CMYK OK' ce qui est plus raisonnable – giordano
Vous pouvez éviter la dépendance sur' pdfinfo' en vérifiant si 'identify' bails sur une page inexistante (quand cela arrive, il vous indique même le nombre de pages.) –
... ce qu'il fait aussi sur la page "-1" –
Le script de Martin SCHARRER est grande. Il contient un bug mineur: Il compte deux pages qui contiennent des couleurs et sont directement consécutives deux fois. J'ai réparé ça. En outre, le script compte maintenant les pages et répertorie les pages en niveaux de gris pour l'impression en double page. En outre, il imprime les pages séparées par des virgules, de sorte que la sortie peut directement être utilisée pour l'impression à partir d'une visionneuse PDF. J'ai ajouté le code, mais vous pouvez également le télécharger en cliquant sur le bouton here.
Cheers, Timeshift
#!/bin/bash
if [ $# -ne 1 ]
then
echo "USAGE: This script needs exactly one paramter: the path to the PDF"
kill -SIGINT $$
fi
FILE=$1
PAGES=$(pdfinfo ${FILE} | grep 'Pages:' | sed 's/Pages:\s*//')
GRAYPAGES=""
COLORPAGES=""
DOUBLECOLORPAGES=""
DOUBLEGRAYPAGES=""
OLDGP=""
DOUBLEPAGE=0
DPGC=0
DPCC=0
SPGC=0
SPCC=0
echo "Pages: $PAGES"
N=1
while (test "$N" -le "$PAGES")
do
COLORSPACE=$(identify -format "%[colorspace]" "$FILE[$((N-1))]")
echo "$N: $COLORSPACE"
if [[ $DOUBLEPAGE -eq -1 ]]
then
DOUBLEGRAYPAGES="$OLDGP"
DPGC=$((DPGC-1))
DOUBLEPAGE=0
fi
if [[ $COLORSPACE == "Gray" ]]
then
GRAYPAGES="$GRAYPAGES,$N"
SPGC=$((SPGC+1))
if [[ $DOUBLEPAGE -eq 0 ]]
then
OLDGP="$DOUBLEGRAYPAGES"
DOUBLEGRAYPAGES="$DOUBLEGRAYPAGES,$N"
DPGC=$((DPGC+1))
else
DOUBLEPAGE=0
fi
else
COLORPAGES="$COLORPAGES,$N"
SPCC=$((SPCC+1))
# For double sided documents also list the page on the other side of the sheet:
if [[ $((N%2)) -eq 1 ]]
then
DOUBLECOLORPAGES="$DOUBLECOLORPAGES,$N,$((N+1))"
DOUBLEPAGE=$((N+1))
DPCC=$((DPCC+2))
#N=$((N+1))
else
if [[ $DOUBLEPAGE -eq 0 ]]
then
DOUBLECOLORPAGES="$DOUBLECOLORPAGES,$((N-1)),$N"
DPCC=$((DPCC+2))
DOUBLEPAGE=-1
elif [[ $DOUBLEPAGE -gt 0 ]]
then
DOUBLEPAGE=0
fi
fi
fi
N=$((N+1))
done
echo " "
echo "Double-paged printing:"
echo " Color($DPCC): ${DOUBLECOLORPAGES:1:${#DOUBLECOLORPAGES}-1}"
echo " Gray($DPGC): ${DOUBLEGRAYPAGES:1:${#DOUBLEGRAYPAGES}-1}"
echo " "
echo "Single-paged printing:"
echo " Color($SPCC): ${COLORPAGES:1:${#COLORPAGES}-1}"
echo " Gray($SPGC): ${GRAYPAGES:1:${#GRAYPAGES}-1}"
#pdftk $FILE cat $COLORPAGES output color_${FILE}.pdf
versions plus récentes de Ghostscript (version 9.05 et versions ultérieures) comprennent un "dispositif" appelé inkcov. Il calcule la couverture d'encre de chaque page (pas pour chaque image) en valeurs Cyan (C), Magenta (M), Jaune (Y) et Noir (K), où 0.00000 signifie 0% et 1.00000 signifie 100% (voir Detecting all pages which contain color).
Par exemple:
$ gs -q -o - -sDEVICE=inkcov file.pdf
0.11264 0.11605 0.11605 0.09364 CMYK OK
0.11260 0.11601 0.11601 0.09360 CMYK OK
Si les valeurs ne sont pas CMY 0, la page est la couleur.
Pour que la sortie des pages qui contiennent des couleurs utilisent cette oneliner pratique:
$ gs -o - -sDEVICE=inkcov file.pdf |tail -n +4 |sed '/^Page*/N;s/\n//'|sed -E '/Page [0-9]+ 0.00000 0.00000 0.00000/d'
Il y a une faute de frappe, ce que SO ne me laissera pas correct car il ne s'agit que d'un caractère: s doit être gs. De plus, cette méthode ne fonctionne pas forcément comme prévu, les fichiers pdf créés par inkscape, par exemple, ont toujours un CMJ non nul même si l'image est purement en niveaux de gris –
Correction de la faute de frappe – Matteo
- 1. Contexte graphique noir et blanc
- 2. Graphics2D: Dessin noir sur blanc?
- 3. Création de LaTeX Beamer Noir et Blanc
- 4. Création de PDF en noir et blanc à partir d'Oracle Reports
- 5. Comment changer l'arrière-plan d'une cellule groupable UITableView en noir (ou non blanc)?
- 6. UIBarButtonItem noir au lieu de blanc
- 7. comment inverser en partie la couleur d'un personnage? (Sa 33% à gauche est en noir et 67% à droite est blanc)
- 8. Qt: QImage enregistre toujours les couleurs transparentes en noir
- 9. Comment savoir si l'applet ou l'application est
- 10. Comment savoir si mon iPhone est en mode silencieux?
- 11. comment savoir si VM est en cours d'exécution en mode serveur ou client?
- 12. Besoin d'aide/réponses PDF couleur seperation
- 13. Test PictureBox en blanc
- 14. Exporter des pages PDF vers une série d'images en Java
- 15. Comment vérifier si les cookies sont bloqués en utilisant JavaScript
- 16. Quelles ressources, en dehors des sites Microsoft, sont disponibles pour en savoir plus sur les applications Web Form et MVC?
- 17. Comment savoir si vos migrations sont à jour avec migratordotnet?
- 18. Fondu d'une couleur au blanc (augmentation de la luminosité)
- 19. Comment savoir si un fichier existe en C#/.NET?
- 20. En Perl, comment savoir si mon fichier est utilisé en tant que module ou en tant que script?
- 21. En Perl, comment savoir si une chaîne est un nombre?
- 22. Comment savoir si une ligne intersecte un polygone en C#?
- 23. Comment puis-je savoir si mon processeur est en 32 ou 64 bits?
- 24. Changer la couleur de police du texte en format PDF
- 25. Comment savoir si urllib.urlretrieve réussit?
- 26. Comment savoir si un formulaire est en mode aide?
- 27. en javascript comment puis-je détecter si un navigateur va afficher ou télécharger un pdf?
- 28. Comment savoir si je cours depuis le GAC ou pas?
- 29. Comment savoir si une application .NET a été compilée en mode DEBUG ou RELEASE?
- 30. Comment éviter l'écran blanc blanc?
Autres suggestions disponibles dans cette question similaire sur TeX StackExchange http://tex.stackexchange.com/questions/53493/detecting-all -pages-which-contain-color – Gareth
Question géniale. Merci. – Geoff