2009-03-13 13 views
55

पीडीएफ फाइलों के एक सेट को देखते हुए, जिनमें कुछ पेज रंग होते हैं और शेष काले & सफेद होते हैं, क्या दिए गए पृष्ठों में से कोई भी पता लगाने के लिए कोई प्रोग्राम है और कौन सा काला & सफेद है? उदाहरण के लिए, एक थीसिस प्रिंट करने में, और केवल रंग पृष्ठों को मुद्रित करने के लिए अतिरिक्त खर्च करना उपयोगी होगा। बोनस अंक किसी ऐसे व्यक्ति के लिए जो डबल पक्षीय प्रिंटिंग खाते में खाता लेता है, और रंगीन प्रिंटर पर एक उचित काला और सफेद पृष्ठ भेजता है यदि उसके बाद विपरीत रंग पर एक रंग पृष्ठ होता है।मुझे कैसे पता चलेगा कि पीडीएफ पेज रंग या काले और सफेद हैं?

+0

अन्य सुझाव उपलब्ध stackexchange http://tex.stackexchange.com/questions/53493/detecting-all -पृष्ठ-जिसमें-रंग-रंग – Gareth

+0

बहुत बढ़िया प्रश्न है। धन्यवाद। – Geoff

उत्तर

27

यह मैंने देखा है सबसे दिलचस्प प्रश्नों में से एक है! मैं बिटमैप को प्रस्तुत करने वाली कुछ अन्य पोस्टों से सहमत हूं और फिर बिटमैप का विश्लेषण करना सबसे विश्वसनीय समाधान होगा। सरल पीडीएफ के लिए, यहां एक तेज़ लेकिन कम पूरा दृष्टिकोण है।

  1. पार्स प्रत्येक पीडीएफ पेज
  2. रंग निर्देशों (छ, rg, कश्मीर, अनुसूचित जाति, SCN, आदि) एम्बेडेड छवियों के लिए
  3. देखो के लिए
  4. देखो,

मेरे समाधान नीचे रंग के विश्लेषण # 1 और # 2 का आधा है। # 2 का दूसरा भाग उपयोगकर्ता द्वारा परिभाषित रंग के साथ पालन करना होगा, जिसमें पेज में/रंगस्पेस प्रविष्टियों को देखना और उन्हें डीकोड करना शामिल है - यदि यह आपके लिए दिलचस्प है, तो मुझे ऑफ़लाइन संपर्क करें, क्योंकि यह बहुत ही कामयाब है लेकिन नहीं 5 मिनट।

सबसे पहले मुख्य कार्यक्रम:

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

और फिर यहां सहायक रेंडरर कि प्रत्येक पृष्ठ पर रंग निर्देशों संभालती है:

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

ImageMagick में छवि तुलना के लिए कुछ अंतर्निहित विधियां हैं।

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

वहाँ ImageMagick के लिए कुछ पर्ल एपीआई, इसलिए हो सकता है अगर आप चतुराई से छवि कनवर्टर करने के लिए एक पीडीएफ के साथ इन गठबंधन आप अपने काले & सफेद परीक्षण करने के लिए एक तरह से प्राप्त कर सकते हैं।

2

यद्यपि वहाँ अन्य आसान समाधान हो सकता है मैं, इस तरह यह करने के लिए कोशिश करेंगे, और मैं उन्हें सुनने के लिए उत्सुक हूँ, मैं सिर्फ यह कोशिश देना चाहता हूँ:

  1. लूप सभी पृष्ठों के माध्यम से
  2. एक छवि
  3. करने के लिए पृष्ठों निकालें छवि

पृष्ठ संख्या के लिए के रंग रेंज सत्यापित करें, तो आप शायद पर्ल के लिए बहुत अधिक प्रयास के बिना that अनुवाद कर सकते हैं। यह मूल रूप से एक regex है। यह भी said है कि:

r "(/ प्रकार) \ s (/ पृष्ठ) [/> \ s]?"

आप बस कितने बार इस नियमित अभिव्यक्ति में होता है गिनती करने के लिए है पीडीएफ फाइल, कम से कम स्ट्रिंग "<>" (रिक्त आयु जो प्रदान नहीं की जाती हैं) को कम करें।

छवि निकालने के लिए, आपको ImageMagick उपयोग कर सकते हैं that क्या करना है। या this question देखें।

आखिरकार, यह काला और सफेद होने के लिए, यह निर्भर करता है कि क्या आपका शाब्दिक रूप से काला और सफेद या ग्रेस्केल है। काले और सफेद के लिए, आपको सभी छवियों में केवल, अच्छी तरह से, काले और सफेद होना चाहिए। यदि आप ग्रेस्केल देखना चाहते हैं, तो अब, यह वास्तव में मेरी विशेषता नहीं है लेकिन मुझे लगता है कि आप देख सकते हैं कि लाल, हरे और नीले रंग का औसत एक दूसरे के करीब है या यदि मूल छवि और grayscale converted प्रत्येक के करीब हैं अन्य।

आशा है कि यह आगे जाने में आपकी सहायता के लिए कुछ संकेत देता है।

+1

पेज गिनती प्राप्त करने के लिए: perl -le'use सीएएम :: पीडीएफ; प्रिंट सीएएम :: पीडीएफ-> नया ("my.pdf") -> numPages ' –

15

यह Image Magick उपकरण identify उपयोग करना संभव है। यदि पीडीएफ पृष्ठों पर प्रयोग किया जाता है तो यह पृष्ठ को पहले रास्टर छवि में परिवर्तित करता है। यदि पृष्ठ में रंग शामिल है तो -format "%[colorspace]" विकल्प का उपयोग करके परीक्षण किया जा सकता है, जो मेरे पीडीएफ के लिए Gray या RGB मुद्रित किया गया है। आईएमएचओ identify (या पृष्ठभूमि में जो भी उपकरण इसका उपयोग करता है; घोस्टस्क्रिप्ट?) रंग के उपहारों के आधार पर रंगस्थान का चयन करता है।

एक उदाहरण है:

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

जहां पृष्ठ 0 से पेज शुरू करने, 1. नहीं पेज चयन सभी पृष्ठों एक के लिए ढह करने, उसका उपयोग नहीं कर रहा है, जो नहीं है कि आप क्या चाहते है।

मैंने निम्नलिखित BASH स्क्रिप्ट लिखी है जो पृष्ठों की संख्या प्राप्त करने के लिए pdfinfo का उपयोग करती है और फिर उन पर लूप करती है। रंग में मौजूद पृष्ठों को आउटपुट करना। मैंने डबल पक्षीय दस्तावेज़ के लिए एक सुविधा भी जोड़ा जहां आपको एक गैर-रंगीन बैकसाइड पृष्ठ की भी आवश्यकता हो सकती है।

outputted अंतरिक्ष पृथक सूची रंग पीडीएफ पृष्ठों 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 
+2

इस टीएक्स फ़ाइल पर विचार करें:' हैलो वर्ल्ड \ बाय '। 'पहचान -format"% [colorpace] "" $ FILE.pdf [0] "' 'sRGB' है, जबकि' gs -o--sDEVICE = inkcov $ FILE.pdf "के साथ आउटपुट (सुझाया गया [यहां] (http://tex.stackexchange.com/a/61216/31416)) मुझे '0.00000 0.00000 0.00000 0.00020 सीएमवाईके ओके 'मिलता है जो अधिक उचित है। – giordano

+0

आप' pdfinfo' पर निर्भरता से बच सकते हैं कि' पहचान 'पूंछ एक गैर-मौजूदा पृष्ठ पर बाहर। (जब ऐसा होता है, तो यह आपको पेज गिनती भी बताता है।) –

+0

... जो यह पृष्ठ "-1" पर भी करता है। –

3

मार्टिन Scharrer से स्क्रिप्ट बहुत अच्छा है। इसमें एक मामूली बग होता है: यह दो पृष्ठों की गणना करता है जिनमें रंग होता है और लगातार दो बार लगातार होता है। मैंने तय किया इसके अलावा स्क्रिप्ट अब पृष्ठों की गणना करता है और डबल-पेजेड प्रिंटिंग के लिए ग्रेस्केल पृष्ठों को सूचीबद्ध करता है। इसके अलावा यह पृष्ठों को अल्पविराम से अलग करता है, इसलिए आउटपुट का उपयोग सीधे पीडीएफ व्यूअर से प्रिंट करने के लिए किया जा सकता है। मैंने कोड जोड़ा है, लेकिन आप इसे here भी डाउनलोड कर सकते हैं।

चीयर्स, शिफ़्ट होने के समय Ghostscript (संस्करण 9.05 और बाद में) की

#!/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 
12

नए संस्करण एक "डिवाइस" inkcov कहा जाता है शामिल हैं। यह सायन (सी), मैजेंटा (एम), पीला (वाई) और ब्लैक (के) मानों में प्रत्येक पृष्ठ (प्रत्येक छवि के लिए नहीं) के स्याही कवरेज की गणना करता है, जहां 0.00000 का मतलब 0% है, और 1.00000 का मतलब 100% है (देखें Detecting all pages which contain color)।

उदाहरण के लिए:

$ 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 

CMY मान 0 नहीं हैं तो पेज का रंग है।

सिर्फ उत्पादन उन पृष्ठों को शामिल रंग इस आसान oneliner का उपयोग करें: टेक्स पर इस समान प्रश्न में

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

एक टाइपो है, जो मुझे नहीं जाने देगा सही क्योंकि यह केवल एक-चरित्र परिवर्तन है: एस जी होना चाहिए। साथ ही, यह विधि आवश्यक रूप से अपेक्षित काम नहीं करती है; पीडीएफ फाइलें इंकस्केप द्वारा बनाई गई हैं, उदाहरण के लिए, हमेशा nonzero CMY होती है, भले ही छवि पूरी तरह से ग्रेस्केल हो। –

+0

धन्यवाद I टाइपो तय किया – Matteo

संबंधित मुद्दे