使用PHP和ImageMagick创建由PDF中的图像填充的数组

时间:2012-06-12 20:53:51

标签: php arrays imagemagick imagick

我正在尝试编写一个例程,该例程将采用用户提交的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手册,没有找到任何关于将多个图像输出到阵列的信息,只发现了一系列保存到磁盘的文件。

更新:(06/13/2012) 我找到了一种方法来实现我所需要的,但它很丑陋,效率低下,而且我肯定很慢,但似乎没有其他办法。

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()不会工作?为什么我不能每次使用setIteratorIndex而不重新初始化/(创建新的?)imagick对象?我必须遗漏一些东西,但文档和谷歌,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上的说明here

1 个答案:

答案 0 :(得分: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();