2

我正在尝试编写一个例程,该例程将获取用户提交的 PDF,并将每个页面提取为图像,然后用这些图像填​​充数组。我发现了几个将所有页面附加到一个图像的示例,但没有一个可以满足我的需要。

这就是我所拥有的,但它返回一个空数组:

function PdfToImg($pdf_in) {
    $img_array = array();
    $im = new imagick();
    $im->readimageblob($pdf_in); // reading image from binary string
    $num_pages = $im->getnumberimages();
    $im->setimageformat("png");

for ($x =1;$x <= $num_pages; $x++) {
    $img = $im->previousimage();
    $img_array .= $img;
    }
    return $img_array;
}

这里的警告之一是我不能将这些文件写入磁盘,必须使用字符串/数组。我查看了 ImageMagick 手册,并没有找到任何关于将多个图像输出到数组的信息,只是输出到保存到磁盘的一系列文件。

更新:(2012 年 6 月 13 日)我找到了一种方法来实现我所需要的,但它很丑陋,效率低下,而且我确信速度很慢,但似乎没有其他方法。

function PdfToImg3($pdf_in) {
    $img_array = array();
    $im = new imagick();
    $im->readimageblob($pdf_in);
    $num_pages = $im->getnumberimages();
    $i = 0;
    for($x = 1;$x <= $num_pages; $x++) {
        $im = new imagick();
        $im->readimageblob($pdf_in);
        $im->setiteratorindex($i);
        $im->setimageformat('png');
        $img_array[$x] = $im->getimageblob();
        $im->destroy();
        $i++;
    }
    $im->destroy();
    return $img_array;
}

生成一个名为 $img_array 的数组,传入 PDF 的页面位于 $img_array 的键中,作为 PNG 图像数据的字符串。

必须有更好的方法,为什么 nextImage() 不起作用?为什么我不能在每次不重新初始化/(创建新的?)imagick 对象的情况下使用 setIteratorIndex?我一定遗漏了一些东西,但文档中存在巨大的漏洞,谷歌、ImageMagick 论坛和 StackOverflow 都不知道这是否成功完成。

测试:非常慢,一个 17 页的简单 PDF 需要将近一分钟。

更新 2:(07/11/2012)在完成了这个代码位进入的更大的项目之后,我决定回到几个点并提高性能。这就是我想出的:

    $img_array = array();
    $im = new imagick();
    $im->readimageblob($pdf_in);
    $num_pages = $im->getnumberimages();
    $im->destroy();
    $i = 0;
    for($x = 1;$x <= $num_pages; $x++) {
        $im = new imagick();
        $im->readimageblob($pdf_in);
        $im->setResolution(300,300);
        $im->setiteratorindex($i);
        $im->setimageformat('png');
        $img_array[$x] = $im->getimageblob();
        $im->destroy();
        $i++;
    }
    return $img_array;

此更改导致 4 页复杂的 PDF 转换从 21-25 秒缩短到大约 2-3 秒。我理解为什么某些更改有所帮助,而其他更改则不太清楚。希望有人会发现这很有用。

UPDATE3:弄清楚为什么性能上升这么多,将“setResolution”移动到“readImageBlob”以下会导致 DPI 设置被忽略,默认为 72。注意到这一点,我将声明移回,并将其减少到 150 并实现结果相似,但性能仍然好得多。在此处查看 php.net 上的注释。

4

1 回答 1

2

这种一直在读取和破坏 blob 的做法可能会拖慢我们的速度,实际上我们根本不需要它们,剥离后的代码如下所示:

$img_array = array();
$im = new imagick();
$im->setResolution(150,150);
$im->readImageBlob($pdf_in);
$num_pages = $im->getNumberImages();
for($i = 0;$i < $num_pages; $i++) 
{
    $im->setIteratorIndex($i);
    $im->setImageFormat('jpeg');
    $img_array[$i] = $im->getImageBlob();
 }
 $im->destroy();
于 2013-05-09T18:20:58.440 回答