有没有办法在 PDF::API2 中强制提前渲染图像?

时间:2021-06-12 01:46:20

标签: perl pdf-generation

这个测试程序

#!/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, 0, 0, 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(主要由这些图像组成)。

我一直在想,边走边清理(每批照片都有自己的临时目录,当我处理完那批照片后,该目录将被删除)是一种礼貌的方式(限制资源使用) )。如果我超出了临时文件系统的容量,我将不得不将它们放在真正的磁盘上,我有足够的空间,但可能会明显变慢。

1 个答案:

答案 0 :(得分:0)

看来您可以使用 update() 而不是 finishobjects() :

$photo->image($img, 0, 0, 400, 600);
$pdf->update();
$tmpFile = undef;
# do something more here..
# Then save the file..
$pdf->save;

编辑:

在调用 update() 后,您似乎需要重新打开 pdf:

$photo->image($img, 0, 0, 400, 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();
相关问题