Supported formats for libvips CLI output to Windows stdout

1.2k views Asked by At

I use libvips to convert HEIC images to a more tractable format and pipe the result to another process without writing to disk. I can do that using PNG as an intermediate format:

vips copy input.heic .png

However the next process in my chain only accepts either BMP images or raw RGB data. If I replace .png with .bmp in the above command I get this error:

input.heic: bad seek to 1811903
VipsForeignSave: ".bmp" is not a known target format

This happens with many other formats including the native .vips. The conversion works fine with all formats if I write to disk instead of to stdout.

It will help being able to convert either to BMP or to a list of integers with the RGB information.

2

There are 2 answers

2
Mark Setchell On BEST ANSWER

Not sure if you are looking for a work-around, or hoping for a software update from John for libvips, or what exactly.

Anyway, I just wanted to say that if you want a work-around to convert vips output to BMP, you could use ppmtobmp which is part of the NetPBM suite.

So, to a file that would be:

vips copy image.heic .ppm | ppmtobmp - > result.bmp

and as a stream filter, without going to disk:

vips copy image.jpg .ppm | ppmtobmp | NextProcess

Note that ppm format is actually RGB with 3-4 lines of ASCII header at the start, which contains the dimensions - try it and see. So, if you can find a way in Windows to delete 3-4 lines of ASCII you can get RGB. Or if your image is 640x480 pixels at 3 bytes/pixel maybe you can find a way on Windows to get the last (640x480x3) bytes of a file, or stream and discard the PPM header that way.

Keywords: HEIC, vips, NetPBM, BMP

8
jcupitt On

You can see the set of supported formats with vips -l. For 8.10, it's:

$ vips -l | grep _target
          VipsForeignSaveCsvTarget (csvsave_target), save image to csv (.csv), priority=0, mono
          VipsForeignSaveMatrixTarget (matrixsave_target), save image to matrix (.mat), priority=0, mono
          VipsForeignSavePpmTarget (ppmsave_target), save to ppm (.ppm, .pgm, .pbm, .pfm), priority=0, rgb
          VipsForeignSaveRadTarget (radsave_target), save image to Radiance target (.hdr), priority=0, rgb
          VipsForeignSavePngTarget (pngsave_target), save image to target as PNG (.png), priority=0, rgba
          VipsForeignSaveJpegTarget (jpegsave_target), save image to jpeg target (.jpg, .jpeg, .jpe), priority=0, rgb-cmyk
          VipsForeignSaveWebpTarget (webpsave_target), save image to webp target (.webp), priority=0, rgba-only
          VipsForeignSaveHeifTarget (heifsave_target), save image in HEIF format (.heic, .heif, .avif), priority=0, rgba-only

.v and .raw might be added in 8.11. .bmp is written by imagemagick rather than libvips and may not make it.

Another alternative is to use something like the Python interface, pyvips, rather than the CLI. For example:

import os
import pyvips

image = pyvips.Image.black(10, 10)
memory = image.write_to_memory()
os.write(1, memory)

Will write the raw bytes (100 zeros in this case) to stdout in binary mode.

To use BMP instead you can write:

memory = image.magicksave_buffer(format="BMP")