libvips rotate在设备上没有剩余空间

时间:2018-04-30 10:03:55

标签: image-processing vips

我正在使用libvips来旋转图像。我使用的是具有3002 MB Ram和512MB临时存储的VM。AWS Lambda Machine。

我运行旋转图像的命令是

vips rot original.jpg rotated.jpg d90

抛出以下错误

Exit Code: 1, Error Output: ERROR: wbuffer_write: write failed unix error: No space left on device

jpg图像大约10Mb。

1 个答案:

答案 0 :(得分:4)

以下是libvips将如何旋转你的jpg图像。

90度旋转需要随机访问图像像素,但JPEG图像只能从上到下严格读取,因此第一步,libvips必须将JPG解压缩为随机访问格式。它使用vips(.v)格式,这几乎是一个带有小标题的C数组。

对于100mb以下的图像(可以更改此值,见下文)解压缩,它将解压缩到内存缓冲区。对于解压缩超过100mb的图像,它将解压缩到/tmp中的临时文件(您可以更改此信息,请参见下文)。

接下来,它会旋转到输出图像。它可以作为单个流操作执行此操作,因此它通常需要足够的内存用于输入图像上的256条扫描线,输出上需要256条,因此在这种情况下大约需要30mb左右的扫描线,以及每个线程的一些工作区域。

在您的特定情况下,输入图像将被解压缩为30,000 x 10,000 x 3字节或大约900mb的临时文件。这超过了/tmp中的512mb,因此操作失败。

最简单的解决方案是强制加载程序通过内存缓冲区加载。如果我尝试:

$ vipsheader x.jpg 
x.jpg: 30000x10000 uchar, 3 bands, srgb, jpegload
$ time vips rot x.jpg y.jpg d90 --vips-progress --vips-leak
vips temp-3: 10000 x 30000 pixels, 8 threads, 128 x 128 tiles, 256 lines in buffer
vips x.jpg: 30000 x 10000 pixels, 8 threads, 30000 x 16 tiles, 256 lines in buffer
vips x.jpg: done in 0.972s          
vips temp-3: done in 4.52s          
memory: high-water mark 150.43 MB
real    0m4.647s
user    0m5.078s
sys 0m8.418s

leakprogress标记使vips报告一些统计信息。你可以看到初始解压缩到临时文件正在谈0.97s,旋转到输出是4.5s,它需要150mb像素缓冲区和900mb光盘。

如果我提高门槛,我会看到:

$ time VIPS_DISC_THRESHOLD=1gb vips rot x.jpg y.jpg d90 --vips-progress --vips-leak
vips temp-3: 10000 x 30000 pixels, 8 threads, 128 x 128 tiles, 256 lines in buffer
vips x.jpg: 30000 x 10000 pixels, 8 threads, 30000 x 16 tiles, 256 lines in buffer
vips x.jpg: done in 0.87s          
vips temp-3: done in 1.98s          
memory: high-water mark 964.79 MB
real    0m2.039s
user    0m3.842s
sys 0m0.443s

现在第二个旋转阶段只有2秒,因为它只是读取内存,但内存使用量已增加到1gb左右。

此系统在此处的libvips文档中引入:

http://jcupitt.github.io/libvips/API/current/How-it-opens-files.md.html