【问题标题】:App Engine PHP generate image thumbApp Engine PHP 生成图片缩略图
【发布时间】:2018-09-04 15:34:05
【问题描述】:

我想使用 imagick 和 PHP
为存储在 Google 存储桶中的 PDF 文件生成缩略图图像 我在 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 用来编写的目录,但我无法做到这一点!

【问题讨论】:

  • 如果目录是“只读”目录,或者换句话说,如果您没有这样做的权限,您将无法在该目录中写入任何数据,1- set正确的权限,或 2- 将您的拇指保存在您有权写入的另一个目录中, 3- 将您的拇指存储在云中(某些 API 或任何其他外部存储)或 4- 将其保存到 MYSQL 等数据存储中(不是一个好的选择
  • 我无法更改添加写入的权限....这在我的情况下是不允许的,我尝试更改 imagick 的写入目录但我无法实现...

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


【解决方案1】:

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

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

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

【讨论】:

  • 我试过你的解决方案,但很抱歉它抛出了这个错误 Uncaught exception 'ImagickException' with message 'UnableToWriteBlob `magick--1lFkoxwYxJHF4': Read-only file system @error/blob.c/BlobToFile /266'
  • 顺便说一句...我可以成功为jpg图像生成缩略图,问题仅在pdf文件中...。
【解决方案2】:

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

App Engine 应用程序不能:

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

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

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

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

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

【讨论】:

  • 移动到 flex 环境对我来说不是一个选项......并且在“$imagick->readimageblob($imagenblob);”这一行抛出异常.... 那是在 setFormat 之前...我在过去 3 天里尝试将 imagick 配置为不使用中间/临时文件但没有运气...
  • 如果有使用 python 的完整解决方案,我可以使用它来代替 PHP
  • 很遗憾没有。我只能指出一种使用内存中StringIO 文件处理程序以避免写入文件系统的潜在有用方法:stackoverflow.com/questions/38885764/…
  • 或写入 GCS 文件的一个示例:stackoverflow.com/questions/35708725/…
【解决方案3】:

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

1) Google App Engine Standard 的沙盒限制

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

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

【讨论】:

  • 我已经尝试过您的解决方案,我将 thumbnailGenerator 文件移动到 Flex Env​​iroment... 现在我面临以下错误“Uncaught ImagickException: Uncaught image blob in /app/thumpnailGenerator.php:31堆栈跟踪:#0 /app/thumpnailGenerator.php(31): Imagick->readimageblob('%PDF-1.3\n%\xC7\xEC\x8F\xA2\n...')"
  • 向我们展示抛出那个的代码?我假设这是来自您的 GAE 标准应用程序读取 GCS img(后处理的缩略图)?
【解决方案4】:

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

Imagick 不适用于 GAE 上的 pdf 文件

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    相关资源
    最近更新 更多