Frage

eine Reihe von PDF-Dateien gegeben, unter denen einige Seiten sind Farbe und die restlichen sind schwarz und weiß, gibt es ein Programm unter den angegebenen Seiten, um herauszufinden, welche Farbe sind und welche sind schwarz und weiß? Dies wäre nützlich, zum Beispiel, eine Diplomarbeit in dem Ausdruck, und nur die Ausgaben zusätzlich die Farbseiten zu drucken. Bonuspunkte für jemanden, der in Betracht beidseitiges Drucken erfolgt, und sendet eine entsprechende Schwarz-Weiß-Seite an den Farbdrucker, wenn sie durch eine Farbseite auf der gegenüberliegenden Seite folgt.

War es hilfreich?

Lösung

Dies ist eines der interessantesten Fragen, die ich je gesehen habe! Ich stimme den anderen Beiträgen mit einigen, die zu einer Bitmap-Rendering und dann analysieren die Bitmap wird die zuverlässigste Lösung sein. Für einfache PDFs, hier ist ein schneller, aber weniger vollständiger Ansatz.

  1. Parse jede PDF-Seite
  2. Suchen Sie nach Farbe Richtlinien (g, rg, k, sc, scn, etc.)
  3. Geben Sie für eingebettete Bilder, analysieren für Farbe

Meine Lösung unten tut # 1 und die Hälfte der # 2. Die andere Hälfte der # 2 wäre mit benutzerdefinierter Farbe zu verfolgen, die die / Color Einträge auf der Seite beinhalten aufzuzublicken und wieder entschlüsselt werden - kontaktieren Sie mich offline, wenn dies für Sie interessant ist, da es sehr machbar ist, aber nicht in 5 Minuten.

Zuerst wird das Hauptprogramm:

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";
   }
}

Und hier sind dann die Helfer-Renderer, Farb Richtlinien auf jeder Seite behandelt:

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(@_); }

Andere Tipps

Neuere Versionen von Ghost (Version 9.05 und später) eine "Vorrichtung" genannt inkcov. Es berechnet die Farbdeckung der jeweiligen Seite (nicht für jedes Bild) in Cyan (C), Magenta (M), Gelb (Y) und Schwarz (K) Werte, wobei 0,00000 Mittel 0% und 1,00000 bedeutet 100% (s < em> Erkennung aller Seiten, die Farbe enthalten ).

Zum Beispiel:

$ 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

Wenn die CMY-Werte nicht 0, dann wird die Seite ist die Farbe.

Um nur Ausgang der Seiten, die Farben verwenden diese handlichen oneliner enthalten:

$ 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'

Es ist möglich, das Image Magick Werkzeug identify zu verwenden. Wenn auf PDF-Seiten verwendet, wandelt sie die Seite zuerst in ein Rasterbild. Wenn die Seite enthaltenen Farbe kann mit der Option -format "%[colorspace]" getestet werden, die für meine PDF entweder Gray oder RGB gedruckt. IMHO identify (oder was auch immer Werkzeug verwendet es im Hintergrund;? Ghostscript). Tut wählt den Farb abhängig von den Geschenken der Farbe

Ein Beispiel ist:

identify -format "%[colorspace]" $FILE.pdf[$PAGE]

wo PAGE ist die Seite ausgehend von 0, nicht 1. Wenn die Seitenauswahl nicht alle Seiten verwendet wird, werden zu einem zusammengelegt werden, was nicht ist, was Sie wollen.

Ich habe den folgenden BASH-Skript, das pdfinfo die Anzahl der Seiten zu erhalten verwendet und dann in einer Schleife über sie. Ausgeben der Seiten, die in der Farbe sind. Ich habe auch eine Funktion für doppelseitiges Dokument, in dem Sie könnte auch eine nicht-farbige Rückseite Seite benötigen.

Mit der ausgegebenen Raumliste getrennt die farbigen PDF-Seiten extrahiert werden können pdftk mit:

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

Das Skript von Martin Scharrer ist groß. Es enthält einen kleinen Bug: Es zählt zwei Seiten, die Farbe enthalten und sind zweimal direkt aufeinanderfolgend. Ich reparierte das. Darüber hinaus zählt das Skript nun die Seiten und listet die Graustufenseiten für doppelseitigen Druck. Auch druckt er die Seiten Komma getrennt, so dass der Ausgang direkt zum Drucken von einem PDF-Viewer verwendet werden. Ich habe den Code hinzugefügt, aber Sie können es herunterladen hier auch .

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

ImageMagick hat einige eingebaute Methoden zum Bildvergleich.

http://www.imagemagick.org/Usage/compare/#type_general

Es gibt einige Perl-APIs für ImageMagick, so vielleicht, wenn Sie klug kombinieren diese mit einem PDF to Image Converter Sie einen Weg finden, können Sie Ihre Schwarz-Weiß-Test zu tun.

Ich würde versuchen, es so zu tun, obwohl es andere einfache Lösungen, und ich bin gespannt, sie zu hören, ich will nur, es versuchen:

  1. Schleife durch alle Seiten
  2. Extrahieren Sie die Seiten auf ein Bild
  3. Überprüfen Sie den Farbbereich des Bildes

Für die Seitenzahl, können Sie wahrscheinlich übersetzen dass ohne allzu großen Aufwand zu Perl . Es ist im Grunde ein regulärer Ausdruck. Es ist auch sagte dass:

  

r "(/ Type) \ s? (/ Seite) [/> \ s]"

     

Sie haben einfach zu zählen, wie viele   mal dieser reguläre Ausdruck kommt   in der PDF-Datei, abzüglich der Zeiten, die Sie   finden Sie die Zeichenfolge „<>“   (Leer Alter, die nicht wiedergegeben).

Um das Bild zu extrahieren, können Sie ImageMagick tun dass . Oder finden Sie unter diese Frage .

Schließlich zu bekommen, ob es schwarz und weiß ist, es hängt davon ab, ob Sie buchstäblich schwarz bedeuten Weiß oder Graustufen. Für Schwarz-Weiß, sollten Sie nur, gut, schwarz und weiß in der ganzen Bild. Wenn Sie Graustufen sehen wollen, jetzt, es ist wirklich nicht meine Spezialität, aber ich denke, man, wenn die Mittelwerte der roten sehen konnte, die grüne und die blaue einander nahe sind oder wenn das Originalbild und ein Graustufen eins sind nahe beieinander umgewandelt

.

Hoffe, dass es einige Hinweise gibt Ihnen helfen, gehen weiter.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top