App Engine PHP 生成图像缩略图

App Engine PHP generate image thumb

我想使用 为存储在 google 存储桶中的 PDF 文件 生成缩略图 图像imagick 和 PHP
我在 google App Engine(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);

也许如果我可以更改 imagick 用来写入的目录,但我无法做到这一点!!

ImageMagick 需要一个临时目录来在委托 decoding/encoding 过程中写入工件。我不熟悉应该使用, but the documents suggest tempnam() & sys_get_temp_dir()

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

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

您正在击中 restrictions of the standard environment sandbox 之一:

An App Engine application cannot:

  • write to the filesystem. PHP applications can use Google Cloud Storage for storing persistent files. Reading from the filesystem is allowed, and all application files uploaded with the application are available.

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

另一种方法是尝试将 imagick 配置为不使用 intermediate/temporary 文件(不知道它是否支持)或使用 in-memory 文件模拟(如果 PHP 支持,我是 python 用户)并通过 Imagick::setFilename.

指定

另一件事是使用 setFormat 而不是 setImageFormatsetImageFormat 上的注释表明它 可能 是可能的进行转换 before/without 写入文件:

To set the format of the entire object, use the Imagick::setFormat method. E.g. load TIFF files, then use setFormat('pdf') on the Imagick object, then writeImagesFile('foo.pdf') or getImagesBlob().

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

1) Google App Engine 标准的沙盒限制

2) Imagick 显然需要本地文件系统访问权限(至少是暂时的)才能工作。

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

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

Imagick 不能很好地处理 GAE 上的 pdf 文件