PDF 페이지가 컬러인지 흑백인지 어떻게 알 수 있습니까?
일부 페이지는 컬러이고 나머지는 흑백 인 PDF 파일 세트가 주어지면 주어진 페이지 중 컬러이고 흑백 인 PDF 파일을 찾을 수있는 프로그램이 있습니까? 예를 들어 이것은 논문을 인쇄하고 컬러 페이지를 인쇄하는 데 추가 비용을 지출하는 경우에 유용합니다. 양면 인쇄를 고려하고 반대편에 컬러 페이지가 뒤 따르는 경우 적절한 흑백 페이지를 컬러 프린터로 보내는 사람에게 보너스 포인트가 주어집니다.
이것은 내가 본 가장 흥미로운 질문 중 하나입니다! 비트 맵으로 렌더링 한 다음 비트 맵을 분석하는 것이 가장 신뢰할 수있는 솔루션이 될 것이라는 다른 게시물에 동의합니다. 간단한 PDF의 경우 더 빠르지 만 덜 완전한 방법이 있습니다.
- 각 PDF 페이지 구문 분석
- 색상 지시문 (g, rg, k, sc, scn 등)을 찾습니다.
- 포함 된 이미지 찾기, 색상 분석
아래 내 솔루션은 # 1과 # 2의 절반을 수행합니다. # 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(@_); }
최신 버전의 Ghostscript (버전 9.05 이상)에는 inkcov라는 "장치"가 포함되어 있습니다. 시안 (C), 마젠타 (M), 노랑 (Y) 및 검정 (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'
Image Magick 도구 를 사용할 수 있습니다 identify
. PDF 페이지에서 사용하는 경우 먼저 페이지를 래스터 이미지로 변환합니다. 페이지에 포함 된 색상을 -format "%[colorspace]"
옵션을 사용하여 테스트 할 수 있는 경우 내 PDF에 대해 Gray
또는 RGB
. IMHO identify
(또는 백그라운드에서 사용하는 도구, Ghostscript?)는 현재 색상에 따라 색상 공간을 선택합니다.
예 :
identify -format "%[colorspace]" $FILE.pdf[$PAGE]
여기서 PAGE는 1이 아닌 0에서 시작하는 페이지입니다. 페이지 선택을 사용하지 않으면 모든 페이지가 하나로 축소됩니다.
pdfinfo
페이지 수를 가져 오는 데 사용하는 다음 BASH 스크립트를 작성하고 페이지를 반복합니다. 컬러 페이지를 출력합니다. 또한 무색 뒷면 페이지도 필요할 수있는 양면 문서 기능을 추가했습니다.
출력 된 공백으로 구분 된 목록을 사용하여 다음을 사용하여 컬러 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 has some built-in methods for image comparison.
http://www.imagemagick.org/Usage/compare/#type_general
There are some Perl APIs for ImageMagick, so maybe if you cleverly combine these with a PDF to Image converter you can find a way to do your black & white test.
I would try to do it like that, although there might be other easier solutions, and I'm curious to hear them, I just want to give it try:
- Loop through all pages
- Extract the pages to an image
- Verify the color range of the image
For the page count, you can probably translate that without too much effort to Perl. It's basically a regex. It's also said that:
r"(/Type)\s?(/Page)[/>\s]"
You simply have to count how many times this regular expression occurs in the PDF file, minus the times you find the string "<>" (empty ages which are not rendered).
To extract the image, you can use ImageMagick to do that. Or see this question.
Finally, to get whether it is black and white, it depends if you mean literally black and white or grayscale. For black and white, you should only have, well, black and white in all the image. If you want to see grayscale, now, it's really not my speciality but I guess you could see if the averages of the red, the green and the blue are close to each other or if the original image and a grayscale converted one are close to each other.
Hope it gives some hints to help you go further.
참고URL : https://stackoverflow.com/questions/641427/how-do-i-know-if-pdf-pages-are-color-or-black-and-white
'developer tip' 카테고리의 다른 글
분기없는 K- 평균 (또는 기타 최적화) (0) | 2020.12.09 |
---|---|
React Router 인증 (0) | 2020.12.09 |
.NET 4에는 기본 제공 JSON 직렬 변환기 / 역 직렬 변환기가 있습니까? (0) | 2020.12.09 |
샌드 박싱 .NET 플러그인에 대한 실용적인 접근 방식을 찾고 있습니다. (0) | 2020.12.09 |
Java에서 System.load ()와 System.loadLibrary의 차이점 (0) | 2020.12.09 |