是否有一个(免费提供的)工具可以检查 PDF 文件是否符合 PDF 标准?
我听说这被称为“飞行前检查”或类似的东西。
答案1
多价有一个免费的(如 beer)pdf 验证工具。它肯定不如 Acrobat preflight 那么强大,但对你来说可能已经足够了。
预检通常不仅仅包括验证是否符合 pdf 格式。它还包括确保字体嵌入、颜色空间正确、图像分辨率合适等。也许你不需要这类东西。
答案2
尝试这些:
- 編輯是一个免费工具,可以对 PDF 进行一些检查,但这些检查主要是语法检查。
- Adobe Acrobat 的预检工具。但它不是免费的。
答案3
有很多网站提供验证 pdf 的服务。请谷歌搜索 pdf、validate、online,你会得到类似这样的地址http://www.pdf-tools.com/pdf/validate-pdfa-online.aspx
缺点是,任何地方的其他人都可能使用你的 pdf 来达到你不喜欢的目的。对于我这个律师来说,这是绝对不行的。
答案4
正如 JorgeGT 指出的那样,pdflatex 输出的 pdf 可能存在错误,这并不是因为 pdflatex 本身存在错误,而是因为您包含的图形存在问题。我认为以下 perl 脚本可能对其他人有帮助。它在 Linux 上运行。它旨在对将包含在 LaTeX 文档中的图形进行预检,旨在捕捉过去给我带来麻烦的东西。我通常会在同一个目录中放置一个 Inkscape .svg 文件,并将该文件渲染为 .pdf、.jpg 或 .png,并且脚本是假设该组织而编写的。
当我有一个使用透明度的 Inkscape 文件时,我发现在发送 pdf 进行翻录之前消除透明度是最安全的。虽然它可能有效,但硬拷贝有时会出现乱码。最简单的方法是使用 Inkscape 将图形渲染为 png 文件,然后使用 imagemagick 从 png 中删除透明度。
我以前遇到过这样的问题:pdf 图形中嵌入了字体,而我却不知道。理论上这没什么大不了的,但在实践中,它导致了 rip 问题。如果您没有权限重新分发您没有意识到嵌入在 pdf 中的字体,您还可能会遇到法律问题。要解决 Inkscape 图形的这个问题,您可以在保存为 pdf 时执行“将文本转换为路径”。
#!/usr/bin/perl
use strict;
# usage:
# preflight_one_fig.pl foo.svg
# Checks whether there is no rendered version of foo.svg.
# Checks whether it was rendered to foo.png. If so, complains if it has transparency.
# Checks whether there is also a foo.pdf. If there is, checks foo.svg and foo.pdf for problems:
# transparency (checked for in the svg)
# fonts embedded in pdf
# bad pdf structure
# pdf older than svg
# If there's a problem, prints a message to stdout and exits with nonzero error code.
# requires the following tools:
# xml_grep (part of ubuntu package xml-twig-tools)
# qpdf (ubuntu package qpdf)
# pdffonts (ubuntu package poppler-utils)
# identify and mogrify (ubuntu package imagemagick)
my $svg = $ARGV[0];
my $pdf = $svg;
$pdf =~ s/\.svg$/.pdf/;
if (-e $pdf) {
my $err = check_pdf($svg,$pdf);
if ($err) {err($err)}
exit(0);
}
else {
# There's no pdf, so there'd better be a .jpg or .png
foreach my $e('jpg','png') {
my $bitmap = $svg;
$bitmap =~ s/\.svg$/.$e/;
if (-e $bitmap) {
if ($e eq 'png') {
my $f = `identify -format '%[channels]' $bitmap`;
if ($f=~/rgba/) {
my $c = "mogrify -background white -flatten -alpha off $bitmap";
# system($c);
err("file $bitmap contains transparency; fix with\n $c\nand then check visually");
}
}
exit(0);
}
}
err("file $svg does not exist as .pdf, .jpg, or .png");
}
sub err {
my $message = shift;
print $message,"\n";
exit(-1);
}
sub check_pdf {
my ($svg,$pdf) = @_;
my $err = check_for_stale_pdf($svg,$pdf);
return $err if $err;
my $err = check_pdf_for_fonts($svg,$pdf);
return $err if $err;
my $err = check_pdf_for_transparency($svg,$pdf);
return $err if $err;
my $err = check_pdf_for_structure($svg,$pdf);
return $err if $err;
return undef;
}
sub check_for_stale_pdf {
my ($svg,$pdf) = @_;
# -M is relative age of file in days, floating point
(-M $svg) > (-M $pdf) or return
"file $pdf is older than file $svg, ".(-M $svg)." < ".(-M $pdf);
return undef;
}
sub check_pdf_for_structure {
my ($svg,$pdf) = @_;
system("qpdf --check $pdf 1>/dev/null 2>/dev/null")==0 or return "bad structure for $pdf detected by qpdf --check:\n";
return undef;
}
sub check_pdf_for_fonts {
my ($svg,$pdf) = @_;
my $fonts = `pdffonts $pdf`;
$fonts =~ /\A.*\n.*\n(.*)/; # strip header lines
my $f = $1;
if ($f ne '') {return "embedded fonts found in file $pdf, made from $svg"}
return undef;
}
sub check_pdf_for_transparency {
my ($svg,$pdf) = @_;
# for efficiency, first do a rough check:
return undef unless `grep -e "opacity:[^1]" $svg`;
# Now do a more reliable check.
# There are three types of opacity: fill-opacity, stroke-opacity, and opacity (applied to whole groups).
my $transp = `xml_grep --cond='*[\@style]' $svg | grep -e "opacity:[^1]"`;
if ($transp ne '') {
# Often we get something like this:
# style="fill:none;fill-opacity:0.75"
# This is harmless because there is no fill, so the transparency of the fill is irrelevant.
while ($transp=~/style\s*=\s*"([^"]*)"/gi) {
my $style = $1;
my %styles = ();
foreach my $item(split /;/,$style) {
if ($item=~/(.*):(.*)/) {$styles{lc($1)} = lc($2)}
}
if (defined $styles{'opacity'} && $styles{"opacity"}<1) {
return report_transparency($svg,$style);
}
foreach my $sf('stroke','fill') {
if ( $styles{$sf} ne 'none' # works correctly if undef
&& defined $styles{"${sf}-opacity"}
&& $styles{"${sf}-opacity"}<1 ) {
return report_transparency($svg,$style);
}
}
}
}
return undef;
}
sub report_transparency {
my ($svg,$style) = @_;
$style =~ /(.{0,22}opacity:[^1].{0,10})/;
my $shorter = $1;
return "transparency found in file $svg : ...$shorter...";
}