【问题标题】:How to store an Intervention image in gridfs/mongodb?如何在 gridfs/mongodb 中存储干预图像?
【发布时间】:2020-06-26 16:15:27
【问题描述】:

在我的应用程序中,有一个调用可能会请求调整图像大小的版本。在调整大小的情况下,我想将调整大小的版本长期存储到 gridfs 上,就像其他图像一样。

我可以轻松地调整图像大小并使用干预 (http://image.intervention.io/getting_started/introduction) 将其返回,但似乎无法将调整大小的图像存储到数据库而不将其保存到临时文件中。

尤其是失败:

$bucket = DB::getMongoDB()->selectGridFSBucket();
$stream = $bucket->openDownloadStreamByName($name);
$document = $bucket->getFileDocumentForStream($stream);
$metadata = $document['metadata']->getArrayCopy();
$file = stream_get_contents($stream);
$img = Image::cache(function($image) use ($file){
    $image->make($file);
}, 60, true);
$img->resize($width, $height, function ($constraint) {
    $constraint->aspectRatio();
    $constraint->upsize();
});
$bucket->uploadFromStream($randomName, $img, ['metadata' => $metadata]);

uploadFromStream 的调用失败:Expected $source to have type "resource" but found "Intervention\Image\CachedImage"

尝试改变: $bucket->uploadFromStream($randomName, $img, ['metadata' => $metadata]);

到:

$bucket->uploadFromStream($randomName, $img->stream('png'), ['metadata' => $metadata]);

只有类型从 Intevention\Image\CachedImage 更改为 GuzzleHttp\Psr7\Stream 时才会导致相同的错误。

现在我可以做:

$img->save('/tmp/test.png')
$stream = fopen('/tmp/test.png')
$bucket->uploadFromStream($randomName, $stream, ['metadata' => $metadata]);

但这非常糟糕,因为:

  1. 它有一个竞争条件。我需要确保使用的文件名是唯一的,否则可能会被覆盖
  2. 它写入磁盘,这意味着它比仅使用内存流要慢得多
  3. 它会写入磁盘,这意味着它会进一步恶化。考虑到这篇文章完全没用,所以我会避免使用它。它可以经常触发。

那么,有没有办法将调整大小的图像保存到 GridFS而不通过磁盘?

【问题讨论】:

  • 你有图片数据流吗?
  • @D.SM 我的代码如上。关键是我获得了一个图像,调整它的大小,我想保存这个调整大小的版本,它是Intervention\Image\CachedImage 的一个实例。这就是我所拥有的。问题是stream 干预方法似乎返回的是 Psr7 流而不是资源。
  • 我建议查看干预和 mongodb 文档,以找出它们支持的常见或最常见的流类型,并根据发现更新您的问题。

标签: php mongodb streaming gridfs intervention


【解决方案1】:

我找到了一个解决方案:您可以使用$img->response()->content() 将二进制数据作为字符串获取,然后您可以使用openUploadStream 来代替uploadFromStream 并写入数据。

完整的工作解决方案是:

$bucket = DB::getMongoDB()->selectGridFSBucket();
$stream = $bucket->openDownloadStreamByName($name);
$document = $bucket->getFileDocumentForStream($stream);
$metadata = $document['metadata']->getArrayCopy();
$file = stream_get_contents($stream);
$img = Image::cache(function($image) use ($file){
    $image->make($file);
}, 60, true);
$img->resize($width, $height, function ($constraint) {
    $constraint->aspectRatio();
    $constraint->upsize();
});
$stream = $bucket->openUploadStream($randomName, ['metadata' => $metadata]);
fwrite($stream, $img->response()->content());
fclose($stream);

【讨论】:

    猜你喜欢
    • 2012-02-06
    • 2014-05-11
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 2021-07-29
    • 2011-12-07
    • 1970-01-01
    • 2011-06-26
    相关资源
    最近更新 更多