pdf - 如何在打印前从 PDF 文本中去除黑色背景

标签 pdf printing colors edit

我有一个黑色背景和白色/黄色文本的 PDF。

如何在打印前去除黑色背景并反转文本颜色?

最佳答案

一般来说,这可能不太容易解决,但如果您有可预测的 PDF 集合(例如,全部来自同一来源),那么您可以像这样一起破解快速解决方案:

  • 安装 CAM::PDF来自 CPAN
  • 运行“getpdfpage.pl my.pdf 1 > page1.txt”获取第1页的图形代码
  • 搜索“rg”以查找 RGB 文本颜色更改的位置(或“RG”表示背景,或者“g”或“G”表示灰度或“k”或“K”表示 CMYK 颜色“sc”或“SC” "用于特殊色彩空间)
  • 编辑 page1.txt 设置你喜欢的颜色
  • 运行“setpdfpage.pl my.pdf 1 page1.txt out.pdf”

  • 所有这些都可以通过编程而不是通过命令行工具来完成。 getpdfpage.pl 和 setpdfpage.pl 是围绕 CAM::PDF API 的简单小包装。

    一般的解决方案是使用 getPageContentTree() 来解析 PDF 页面语法并搜索颜色更改运算符并更改它们。但是如果您的 PDF 使用自定义颜色空间(“sc”),这可能会很棘手。根据几何形状,搜索执行整页黑色填充的运算符也可能很困难。

    如果您提供示例 PDF 的 URL,我可以提供一些更具体的建议。

    更新:一时兴起,我写了一个可能适用于某些 PDF 的基本颜色转换器脚本。要使用它,请像这个例子一样运行,它将任何红色元素变成绿色:
    perl recolor.pl input.pdf '1 0 0 rg' '0 1 0 rg' out.pdf
    

    这要求您了解您尝试更改的颜色指令的 PDF 语法,因此它可能仍然需要类似于上面推荐的 getpdfpage.pl 步骤的内容。

    和源代码:
    #!/usr/bin/perl -w                      
    
    use strict;
    use CAM::PDF;
    use CAM::PDF::Content;
    
    my %COLOROPS = map {$_ => 1} qw(rg RG g G k K sc SC);
    
    my $pdf = CAM::PDF->new(shift) || die $CAM::PDF::errstr;
    my @oldcolors;
    my @newcolors;
    while (@ARGV >= 2) {
       push @oldcolors, parseColor(shift);
       push @newcolors, parseColor(shift);
    }
    my $out = shift || '-';
    
    for my $p (1 .. $pdf->numPages) {
       my $page = $pdf->getPageContentTree($p);
       traverse($page->{blocks});
       $pdf->setPageContent($p, $page->toString());
    }
    $pdf->cleanoutput($out);
    
    sub parseColor {
       my ($in) = @_;
       my $ops = CAM::PDF::Content->new($in);
       die 'Invalid color syntax in ' . $in if !$ops->validate();
       my @blocks = @{$ops->{blocks}};
       die 'Expected one color operator in ' . $in if @blocks != 1;
       my $color = $blocks[0];
       die 'Not a color operator in ' . $in if !exists $COLOROPS{$color->{name}};
       return $color;
    }
    
    sub traverse {
       my ($blocks) = @_;
       for my $op (@{$blocks}) {
          if ($op->{type} eq 'block') {
             traverse($op->{value});
          } elsif (exists $COLOROPS{$op->{name}}) {
           COLOR:
             for (my $i=0; $i < @oldcolors; ++$i) {
                my $old = $oldcolors[$i];
                if ($old->{name} eq $op->{name} && @{$old->{args}} == @{$op->{args}}) {
                   for (my $v=0; $v < @{$op->{args}}; ++$v) {
                      next COLOR if $old->{args}->[$v]->{value} != $op->{args}->[$v]->{value};
                   }
                   # match! so we will replace                                                                                  
                   $op->{name} = $newcolors[$i]->{name};
                   @{$op->{args}} = @{$newcolors[$i]->{args}};
                   last COLOR;
                }
             }
          }
       }
    }
    

    关于pdf - 如何在打印前从 PDF 文本中去除黑色背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1488554/

    相关文章:

    c# - LibreOffice 在 ASP.NET MVC 中将 XLSX 转换为 PDF

    python - 打印多个没有空格的对象

    c - 在 C 中打印不同格式的文件时需要帮助吗?

    c# - 在 C# 中为 Print Spooler API 设置标志?

    java - 使用 Java,我可以将人类可读的颜色名称转换为整数数组吗?

    pdf - Pandoc和外来字符

    pdf - 生成的签名 PDF 使 Adob​​e Reader 崩溃,但其他 PDF 阅读器不会崩溃

    ios - 将 pdf 页面加载到 UIWebView 中

    ios - 更改所有应用程序配色方案

    perl - 如何设置 Gtk2::Button 的文本颜色?