将pdf的第一页转换为jpg时收到无效文件名错误

6
我正在使用imagick将pdf转换为jpg,如果我提供上传的pdf的直接路径而不指定页面,则脚本可以正常工作。但是,当我在文件路径的末尾添加[0]以指定我只想读取第一页时,它就会崩溃并显示以下错误:

"致命错误:未捕获异常'ImagickException',消息为'提供的文件名无效' Imagick->readImage()"

我也尝试过直接在构造函数中使用'/path/to/file.pdf[0]',但没有成功,但是如果没有页面限定符号,则可以正常工作。根据文档,这应该是可以正常工作的。那么我错在哪里了?
$doc_preview = new Imagick();
$doc_preview->setResolution(180,180);
$doc_preview->readImage('/path/to/file.pdf[0]');
$doc_preview->setImageFormat('jpeg');
$doc_preview->writeImage('/path/to/file.jpg');
$doc_preview->clear();
$doc_preview->destroy();

更新:我应该提到我正在使用HHVM。不确定这在这种情况下是否有差别...但我是。

更新2:我已经在HHVM的github仓库上开了一个问题。希望他们能修复这个错误......在那之前,我标记为正确的答案是一个不错的(虽然是hacky)解决方法。


这是一个bug。该功能不受支持,但在PHP手册中无处不在地重复出现。重复:http://stackoverflow.com/q/11114747/1163786 在此使用setIteratorIndex()解决方案:http://stackoverflow.com/a/22673725/1163786 - Jens A. Koch
好发现...我通过阅读所有支持的方法找到了答案...但是...最好说它不直观。我也不认为我的解决方案是重复的,因为我并没有尝试迭代和生成多个图像...因此之前搜索时无法找到那个解决方案。 - kevindeleon
抱歉,Kevin - 我没有注意到这个问题与HHVM扩展有关。 - Jens A. Koch
3个回答

4

好的...因此,在我的情况下(有点糟糕),解决这个问题的方法是使用fopen(),然后使用setIteratorIndex(0),这是非常不直观的。但对于那些遇到相同问题的人...就是这样!

$pdf_handle = fopen('/path/to/file.pdf', 'rb');

$doc_preview = new Imagick();
$doc_preview->setResolution(180,180);
$doc_preview->readImageFile($pdf_handle);
$doc_preview->setIteratorIndex(0);
$doc_preview->setImageFormat('jpeg');
$doc_preview->writeImage('/path/to/file.jpg');
$doc_preview->clear();
$doc_preview->destroy();

1

readImage() 要求 $filename 是绝对路径。

如果想使用相对路径,则需在其上使用 realpath(),将相对路径转换为绝对文件路径。

替代

$imagick->readImage('/path/to/file.pdf[0]');

尝试。
$imagick->readImage(realpath("/path/to/file.pdf")."[0]");

除了我已经使用绝对服务器路径...而不是相对路径...这就是为什么如果我不在结尾使用页面指定符,它能够工作的原因。问题出在PHP/Imagemagick不能接受带有页面指定符的文件名,如果路径也给出的话...这似乎是一个漏洞。它应该接受带有页面指定符的文件名或带有页面指定符的完整文件路径,但它没有。我会进行测试以确保。 - kevindeleon

1

我的电脑上没有Imagick,但我可以猜测问题出在哪里。问题在于当您使用页面部分打开PDF文件时,您不能包含包含斜杠的目录路径字符串。 我认为是因为我在php.net上阅读了readImage函数页面 http://php.net/manual/en/imagick.readimage.php ,他们没有包含目录路径,所以我认为那是一个小故障但继续。 您应该尝试使用chdir()http://php.net/manual/en/function.chdir.php)更改到PDF文件的目录,然后像这样尝试同一函数$doc_preview->readImage('file.pdf[0]');而不需要目录路径。很可能会起作用。 有些API存在缺陷,您必须解决它们。


我很感激你的猜测,但我不确定使用 chdir() 是一个好的选择。如果这真的是问题的原因...那就是一个令人失望的 bug。 - kevindeleon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接