libvips rotate 没有 space 留在设备上
libvips rotate is throwing no space left on device
我正在使用 libvips 来旋转图像。我正在使用具有 3002 MB Ram 和 512MB 临时内存的 VM storage.The 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。
以下是 libvips 将如何旋转您的 jpg 图像。
90 度旋转需要随机访问图像像素,但 JPEG 图像只能严格读取 top-to-bottom,因此作为第一步,libvips 必须将 JPG 解压缩为随机访问格式。它为此使用 vips (.v) 格式,这几乎是一个带有小 header.
的 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
leak
和 progress
标志使 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
我正在使用 libvips 来旋转图像。我正在使用具有 3002 MB Ram 和 512MB 临时内存的 VM storage.The 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。
以下是 libvips 将如何旋转您的 jpg 图像。
90 度旋转需要随机访问图像像素,但 JPEG 图像只能严格读取 top-to-bottom,因此作为第一步,libvips 必须将 JPG 解压缩为随机访问格式。它为此使用 vips (.v) 格式,这几乎是一个带有小 header.
的 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
leak
和 progress
标志使 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