문제

일부 페이지가 색상이고 나머지는 흑백 인 PDF 파일 세트가 주어지면 색상이고 흑백 인 주어진 페이지 중에서 찾을 수있는 프로그램이 있습니까? 예를 들어 논문을 인쇄 할 때 유용하고 색상 페이지를 인쇄하는 데 추가 비용을 소비합니다. 양면 프린팅을 고려하고 반대쪽의 컬러 페이지가 이루어지면 컬러 프린터로 적절한 검은 색과 흰색 페이지를 보내는 사람의 보너스 포인트.

도움이 되었습니까?

해결책

이것은 내가 본 가장 흥미로운 질문 중 하나입니다! 비트 맵으로 렌더링 한 다음 비트 맵을 분석하는 다른 게시물에 동의하는 것이 가장 안정적인 솔루션이됩니다. 간단한 PDF의 경우 더 빠르지 만 덜 완전한 접근 방식이 있습니다.

  1. 각 PDF 페이지를 구문 분석하십시오
  2. 색상 지침 찾기 (G, RG, K, SC, SCN 등)
  3. 임베디드 이미지를 찾고 색상을 분석하십시오

아래의 내 솔루션은 #2의 #1과 절반을 수행합니다. #2의 나머지 절반은 사용자 정의 색상으로 후속 조치를 취하는 것입니다. 여기에는 페이지에서 /Colorspace 항목을 찾고 디코딩하는 것이 포함됩니다. 매우 가능하지만 흥미로운 경우 오프라인으로 연락하십시오. 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(@_); }

다른 팁

최신 버전 고스트 스크립트 (버전 9.05 이상)에는 Inkcov라는 "장치"가 포함되어 있습니다. 시안 (C), Magenta (M), Yellow (Y) 및 Black (K) 값에서 각 페이지 (각 이미지가 아님)의 잉크 적용 범위를 계산합니다. 0.00000은 0%를 의미하며 1.00000은 100%를 의미합니다 (참조). 색상이 포함 된 모든 페이지를 감지합니다).

예를 들어:

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

사용하는 것이 가능합니다 이미지 magick 도구 identify. PDF 페이지에서 사용되면 먼저 페이지를 래스터 이미지로 변환합니다. 페이지가 포함 된 색상을 사용하여 테스트 할 수있는 경우 -format "%[colorspace]" 내 PDF에 대해서도 옵션 Gray 또는 RGB. IMHO identify (또는 백그라운드에서 사용하는 도구; 고스트 스크립트?) 색상의 선물에 따라 Colorspace를 선택합니까?

예는 다음과 같습니다. 예는 다음과 같습니다. 예는 다음과 같습니다.

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

페이지가 0에서 시작하는 페이지는 1이 아닙니다. 페이지 선택이 사용되지 않으면 모든 페이지가 하나로 무너지면 원하는 것이 아닙니다.

나는 다음과 같은 bash 스크립트를 썼다 pdfinfo 페이지 수를 얻은 다음 루프를 통해. 색상 인 페이지를 출력합니다. 또한 컬러 뒷면 페이지가 필요할 수있는 양면 문서의 기능도 추가했습니다.

출력 공간 분리 목록 사용 색상 PDF 페이지는 사용하여 추출 할 수 있습니다. 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

Martin Scharrer의 대본은 훌륭합니다. 사소한 버그가 포함되어 있습니다. 색상이 포함되어 있고 직접 연속적인 두 페이지를 계산합니다. 나는 그것을 고쳤다. 또한 스크립트는 이제 페이지를 계산하고 이중 페이지 인쇄용 회색조 페이지를 나열합니다. 또한 쉼표를 분리 한 페이지를 인쇄하므로 출력은 PDF 뷰어에서 인쇄하는 데 직접 사용할 수 있습니다. 코드를 추가했지만 다운로드 할 수 있습니다. 여기, 도.

건배, 시간 쉬프트

#!/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에는 이미지 비교를위한 몇 가지 내장 방법이 있습니다.

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

Imagemagick에 대한 일부 Perl API가 있으므로 PDF와 이미지 변환기와 영리하게 결합하면 흑백 테스트를 수행 할 수있는 방법을 찾을 수 있습니다.

다른 해결책이있을 수 있지만 듣기가 궁금하지만, 나는 그것을 시도하고 싶습니다.

  1. 모든 페이지를 루프하십시오
  2. 페이지를 이미지로 추출하십시오
  3. 이미지의 색상 범위를 확인하십시오

페이지 수는 아마도 번역 할 수 있습니다 저것 Perl에 너무 많은 노력을 기울이지 않고. 기본적으로 정규식입니다. 그것은 또한입니다 말했다 저것:

r "(/type) s? (/page) [/> s]

PDF 파일 에서이 정규 표현식이 몇 번이나 발생하는지를 셀 수 있습니다. 문자열 "<>"을 찾는 시간을 빼고 (렌더링되지 않은 빈 연령).

이미지를 추출하려면 사용할 수 있습니다 Imagemagick 할 것 저것. 또는 참조 이 질문.

마지막으로, 그것이 흑백인지 여부를 얻으려면 문자 그대로 흑백 또는 회색 스케일을 의미하는지 여부에 따라 다릅니다. 흑백의 경우 모든 이미지에 흑백 만 있어야합니다. 그레이 스케일을보고 싶다면 지금은 내 전문 분야가 아니지만 빨간색, 녹색과 파란색의 평균이 서로 가까이 있는지 또는 원본 이미지와 그레이 스케일이 변환되었습니다 하나는 서로 가깝습니다.

그것이 당신이 더 나아가도록 도와 줄 힌트를주기를 바랍니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top