问题描述
这个测试程序
#!/usr/bin/env perl
# Test program for multiple-page tifs with pictures -- when must the
# file exist? And can I force that to end earlier?
use strictures 2;
use utf8;
use PDF::API2;
use Path::Tiny qw ( path tempdir tempfile );
my $pdf = PDF::API2->new( -file => "t001.pdf" );
$pdf->mediaBox(11 * 72,8.5 * 72);
my $page = $pdf->page;
# Add image to page
my $photo = $page->gfx;
my $photoFile = path('mcplay/pcd 138-02.jpg');
my $tmpFile = tempfile();
$photoFile->copy ($tmpFile);
my $img = $pdf->image_jpeg($tmpFile->stringify);
$photo->image($img,400,600);
# Does "finishing" the objects remove the further need for the file?
$pdf->finishobjects($photo,$page);
$tmpFile = undef; # Remove the temp file before save
# Yes,this duplicates the observed error in the more complex code
# And finish the page and the file
print "point 1\n";
$pdf->save;
print "point 10\n";
$pdf->end();
print "point 20\n";
在“第 1 点”后失败并显示错误“无法在 /usr/local/lib/perl5/site_perl/PDF/API2/Basic/PDF/Dict.pm 第 196 行打开 /tmp/Ca6uBG0inC。”
如果我删除行 $tmpFile = undef;
,问题就会消失(并生成包含预期图像的有效 PDF)。
鉴于您可以按任何顺序制作页面,然后再返回并修改它们,我可以看到 PDF 的最终渲染是如何被推迟的。我添加了 finishobjects()
调用,希望能在那时强制渲染,但显然不是。该文档非常简洁地说明了 finishobjects()
应该做什么。
有没有办法强制图像的早期渲染,所以我不需要在运行结束时保留临时文件? (在“真实”代码中,临时文件是根据我生成的 PDF 的需要调整大小的图像版本,而不是简单的副本。)
显然,我可以重新排列代码以在保存并关闭 PDF 之前不删除临时目录(上面的示例使用一个临时文件,但实际代码将多个文件复制到一个临时目录中)。但是...在某些用途中,我认为这些临时目录中会有数以万计的中等分辨率图像,对于大小为 50GB 左右的 PDF(主要由这些图像组成)。
我一直在想,边走边清理(每批照片都有自己的临时目录,当我处理完那批照片后,该目录将被删除)是一种礼貌的方式(限制资源使用) )。如果我超出了临时文件系统的容量,我将不得不将它们放在真正的磁盘上,我有足够的空间,但可能会明显变慢。
解决方法
看来您可以使用 update() 而不是 finishobjects()
:
$photo->image($img,400,600);
$pdf->update();
$tmpFile = undef;
# do something more here..
# Then save the file..
$pdf->save;
编辑:
在调用 update()
后,您似乎需要重新打开 pdf:
$photo->image($img,600);
$pdf->update();
$pdf->end();
$tmpFile = undef;
# Reopen the file to do something more with it..
$pdf = PDF::API2->open("t001.pdf" );
# do something more here..
# Then save the file..
$pdf->update();
$pdf->end();