当前位置:  开发笔记 > 编程语言 > 正文

我如何知道PDF页面是彩色还是黑白?

如何解决《我如何知道PDF页面是彩色还是黑白?》经验,为你挑选了3个好方法。

给定一组PDF文件,其中一些页面是彩色的,其余的是黑白的,是否有任何程序可以在给定的页面中查找颜色,哪些是黑白?例如,这可以用于打印论文,并且仅花费额外的费用来打印彩色页面.考虑到双面打印的人的奖励积分,并且如果彩色打印机后面是彩色页面,则向彩色打印机发送适当的黑白页面.



1> Chris Dolan..:

这是我见过的最有趣的问题之一!我同意其他一些渲染到位图的帖子,然后分析位图将是最可靠的解决方案.对于简单的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(@_); }



2> Matteo..:

较新版本的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'



3> Martin Schar..:

可以使用Image Magick工具identify.如果在PDF页面上使用,它会首先将页面转换为光栅图像.如果包含颜色的页面可以使用-format "%[colorspace]"选项进行测试,该选项适用于我的PDF打印GrayRGB.恕我直言identify(或它在背景中使用的工具; Ghostscript?)确实根据颜色的呈现选择颜色空间.

一个例子是:

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

其中PAGE是从0开始的页面,而不是1.如果未使用页面选择,则所有页面将折叠为一个,这不是您想要的.

我编写了以下BASH脚本,用于pdfinfo获取页面数,然后循环遍历它们.输出彩色页面.我还为双面文档添加了一个功能,您可能还需要一个非彩色的背面页面.

使用输出的空格分隔列表,可以使用pdftk以下方法提取彩色PDF页面:

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


考虑一下这个TeX文件:`hello world\bye`.`identify -format"%[colorspace]""$ 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 CMYK OK`更合理.
推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有