【发布时间】: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]);
但这非常糟糕,因为:
- 它有一个竞争条件。我需要确保使用的文件名是唯一的,否则可能会被覆盖
- 它写入磁盘,这意味着它比仅使用内存流要慢得多
- 它会写入磁盘,这意味着它会进一步恶化。考虑到这篇文章完全没用,所以我会避免使用它。它可以经常触发。
那么,有没有办法将调整大小的图像保存到 GridFS而不通过磁盘?
【问题讨论】:
-
你有图片数据流吗?
-
@D.SM 我的代码如上。关键是我获得了一个图像,调整它的大小,我想保存这个调整大小的版本,它是
Intervention\Image\CachedImage的一个实例。这就是我所拥有的。问题是stream干预方法似乎返回的是 Psr7 流而不是资源。 -
我建议查看干预和 mongodb 文档,以找出它们支持的常见或最常见的流类型,并根据发现更新您的问题。
标签: php mongodb streaming gridfs intervention