App Engine PHP生成图像拇指

时间:2018-03-26 13:11:16

标签: php google-app-engine pdf google-cloud-platform imagick

我希望使用 imagick 和PHP支持生成存储在Google存储桶中的 PDF文件的缩略图图像 我在谷歌应用引擎(GAE)标准环境上部署我的应用程序 问题是我一直收到这个错误

Fatal error: Uncaught exception 'ImagickException' with message  
'UnableToWriteBlob `magick--1noB3XBwJhgfn': Read-only file system

我知道应用程序部署到的文件系统是不可写的,但我需要一种方法来实现这个...

这是我的代码

<?php
putenv('MAGICK_TEMPORARY_PATH='.sys_get_temp_dir());

$imagick = new Imagick();

// get the content of pdf url
$imagenblob=file_get_contents('http://www.pdf995.com/samples/pdf.pdf');      

// read the content and load it inn imagick instance
$imagick->readimageblob($imagenblob);                                        

// point to the first page, because I want thumbnail for first page
$imagick->setIteratorIndex(0);        

// set image format
$imagick->setImageFormat('png');       

// resize image
$imagick->resizeImage(320,320,Imagick::FILTER_LANCZOS,1,1);

// return the result
header("Content-Type: image/png");          
$base64 = 'data:image/png;base64,' . base64_encode($imagick);
exit($base64);

也许如果我可以改变想象用来写的目录,但我无法实现这个目标!!

4 个答案:

答案 0 :(得分:2)

由于两种相反的力量在起作用,没有真正的方法可以完成这项工作:

1)Google App Engine Standard的沙箱限制 2)Imagick显然需要本地文件系统访问(至少是暂时的)才能工作。

因此,如果您无法改变Imagick的工作方式,那么唯一剩下的解决方案就是不使用GAE标准。您可以使用GAE Flex或Google Compute Engine。我不知道为什么Flex不适合你;你不需要移动整个项目。您可以在同一项目中的GAE Flex上将此部分作为microservice移植。该服务的唯一功能是处理图像并获取缩略图。然后,您可以将缩略图放在Google云端存储分区中,以便用于应用的其余部分(使用GAE标准版)。

答案 1 :(得分:1)

ImageMagick需要临时目录来在委托解码/编码过程中编写工件。我不熟悉,但文档建议应使用tempnam() & sys_get_temp_dir()

putenv('MAGICK_TEMPORARY_PATH='.sys_get_temp_dir());
$imagick = new Imagick(); 
// ...

另请注意,ImageMagick使用Ghostscript进行PDF解码。验证是否已安装gs二进制文件&amp;如果使用PDF文件,则可用。

答案 2 :(得分:1)

您正在点击其中一个restrictions of the standard environment sandbox

  

App Engine应用程序不能:

     
      
  • 写入文件系统。 PHP应用程序可以使用Google Cloud Storage来存储持久文件。从文件系统中读取是   允许,以及随应用程序上传的所有应用程序文件   可用。
  •   

一种选择(成本更高)是使用灵活的环境,但没有这种限制。

另一种方法是尝试将imagick配置为不使用中间/临时文件(如果它支持,则不知道)或使用内存中文件模拟(如果PHP支持,请不要使用它,我&#39; ma python用户)并通过Imagick::setFilename指定。

要尝试的另一件事是使用setFormat而不是setImageFormatsetImageFormat上的注释表明可能可以在之前进行转换/无需写入文件:

  

要设置整个对象的格式,请使用Imagick :: setFormat   方法。例如。加载TIFF文件,然后在Imagick上使用setFormat(&#39; pdf&#39;)   对象,然后是writeImagesFile(&#39; foo.pdf&#39;)或getImagesBlob()。

答案 3 :(得分:0)

面对同样问题的任何人,我通过创建一个新的Google Compute Engine解决了我的问题,在其上安装了PHP,我创建了一个函数,使用Imagick将pdf转换为图像,并将响应作为base64流返回。

Imagick与GAE上的pdf文件不兼容