简体   繁体   English

App Engine PHP 生成图像缩略图

[英]App Engine PHP generate image thumb

I want to generate a thumbnail image for a PDF file stored on google bucket using imagick and PHP我想使用imagick和 PHP 为存储在谷歌存储桶上的PDF 文件生成缩略图
I deploy my application on google app engine(GAE) standard environment我在谷歌应用引擎(GAE)标准环境中部署我的应用程序
the problem is that I keep getting this error问题是我不断收到此错误

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

I know that the file system the application is deployed to is not writable, but I need a way to achieve this...我知道应用程序部署到的文件系统不可写,但我需要一种方法来实现这一点......

this is my code这是我的代码

<?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);

Maybe if I can change the directory which imagick use to write, but I was not able to achieve this !!也许如果我可以更改 imagick 用来写入的目录,但我无法做到这一点!!

ImageMagick requires a temp directory to write artifacts during the delegate decoding/encoding process. ImageMagick 需要一个临时目录来在委托解码/编码过程中写入工件。 I'm not familiar with我不熟悉 , but the documents suggest tempnam() & sys_get_temp_dir() should be used. ,但文件建议应使用tempnam()sys_get_temp_dir()

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

Also note, Ghostscript is used by ImageMagick for PDF decoding.另请注意,ImageMagick 使用 Ghostscript 进行 PDF 解码。 Verify that the gs binary is installed & available if working w/ PDF files.如果使用 PDF 文件工作,请验证gs二进制文件是否已安装和可用。

You're hitting one of the restrictions of the standard environment sandbox :您遇到了标准环境沙箱限制之一

An App Engine application cannot: App Engine 应用程序不能:

  • write to the filesystem.写入文件系统。 PHP applications can use Google Cloud Storage for storing persistent files. PHP 应用程序可以使用Google Cloud Storage来存储持久性文件。 Reading from the filesystem is allowed, and all application files uploaded with the application are available.允许从文件系统读取,并且所有与应用程序一起上传的应用程序文件都可用。

One option (more costly) would be to use the flexible environment, which doesn't have such restriction.一种选择(成本更高)是使用没有此类限制的灵活环境。

Another approach would be to try to configure imagick to not use intermediate/temporary files (no clue if it supports that) or to use in-memory file emulation (donno if PHP supports that, I'm a python user) and specify that via Imagick::setFilename .另一种方法是尝试将imagick配置为不使用中间/临时文件(不知道它是否支持)或使用内存文件模拟(如果 PHP 支持,则不要,我是 python 用户)并通过Imagick::setFilename

Another thing to try would be using setFormat instead of setImageFormat , the notes on the setImageFormat suggest that it might be possible to make the transformations before/without writing to the file:尝试将使用另一件事setFormat而不是setImageFormat ,在音符setImageFormat表明,有可能使/前的转换,而无需编写的文件:

To set the format of the entire object, use the Imagick::setFormat method.要设置整个对象的格式,请使用 Imagick::setFormat 方法。 Eg load TIFF files, then use setFormat('pdf') on the Imagick object, then writeImagesFile('foo.pdf') or getImagesBlob().例如,加载 TIFF 文件,然后在 Imagick 对象上使用 setFormat('pdf'),然后使用 writeImagesFile('foo.pdf') 或 getImagesBlob()。

There's no real way to make this work due to the two opposing forces at play:由于两种相反的力量在起作用,没有真正的方法可以使这项工作发挥作用:

1) Google App Engine Standard's sandbox limitations 1) Google App Engine Standard 的沙盒限制

2) Imagick apparently needing local file system access (at least temporarily) in order to work. 2)Imagick 显然需要本地文件系统访问(至少暂时)才能工作。

So if you can't change how Imagick work, then the only remaining solution is to not use GAE Standard.因此,如果您无法改变 Imagick 的工作方式,那么剩下的唯一解决方案就是不使用 GAE 标准。 You can either use GAE Flex or Google Compute Engine.您可以使用 GAE Flex 或 Google Compute Engine。 I don't know why Flex is not an option for you;我不知道为什么 Flex 不适合您; you don't need to move the whole project over.你不需要移动整个项目。 You can just port this part over as a microservice on GAE Flex in the same project.您可以将这部分移植为同一项目中 GAE Flex 上的微服务 The sole function of the service would be to process the image and get the thumbnail.该服务的唯一功能是处理图像并获取缩略图。 You can then place the thumbnail in a Google Cloud Storage bucket for the rest of your app (in GAE Standard) to use.然后,您可以将缩略图放在 Google Cloud Storage 存储分区中,供您的应用程序的其余部分(在 GAE 标准中)使用。

to anyone facing the same problem , I solved mine by created a new Google Compute Engine , with PHP installed on it, I created a function to convert the pdf to image using Imagick and it returns the response as base64 stream.对于面临同样问题的任何人,我通过创建一个新的 Google Compute Engine 解决了我的问题,并在其上安装了 PHP,我创建了一个函数来使用 Imagick 将 pdf 转换为图像,并将响应作为 base64 流返回。

Imagick does not work well with pdf files on GAE Imagick 不能很好地处理 GAE 上的 pdf 文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM