【问题标题】:Supported formats for libvips CLI output to Windows stdout支持的 libvips CLI 输出到 Windows 标准输出的格式
【发布时间】:2020-11-26 20:39:01
【问题描述】:

我使用libvips 将HEIC 图像转换为更易于处理的格式,并将结果通过管道传输到另一个进程而不写入磁盘。我可以使用PNG 作为中间格式:

vips copy input.heic .png

但是,我的链中的下一个进程只接受 BMP 图像或原始 RGB 数据。如果我在上述命令中将.png 替换为.bmp,我会收到此错误:

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

许多其他格式都会出现这种情况,包括原生 .vips。如果我写入磁盘而不是stdout,则转换适用于所有格式。

这将有助于能够转换为 BMP 或带有 RGB 信息的整数列表。

【问题讨论】:

    标签: stdout bmp image-conversion vips heic


    【解决方案1】:

    您可以使用vips -l 查看支持的格式集。对于 8.10,它是:

    $ 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 和 .raw 可能会在 8.11 中添加。 .bmp 是由 imagemagick 而不是 libvips 编写的,可能不会成功。

    另一种选择是使用 Python 接口 pyvips 之类的东西,而不是 CLI。例如:

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

    将以二进制模式将原始字节(本例中为 100 个零)写入标准输出。

    要改用 BMP,您可以编写:

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

    【讨论】:

    • 那个 Python 接口很有趣,我会看看调用 .py 是否不会减慢我的链。我不知道标准输出的导出格式子集。我的直觉期望相同的格式能够写入标准输出和磁盘。出于好奇,这种区别有什么原因吗?
    • write-to-filedescriptor 系统是去年才添加的,目前还没有对所有内容进行修改以支持它。 pyvips 可以比 CLI 快很多,因为不需要任何临时文件——libvips 是一个流式图像处理库,所以如果你在一个进程中执行一系列操作,它们都会同时执行,并行且没有中间体。这有点像用管道连接进程,除了它也可以做坐标变换之类的事情。
    • 关于写入文件描述符系统的一些注意事项:libvips.github.io/libvips/2019/11/29/…
    • 非常有教育意义的阅读!我工作的最终目标是 Matlab 的 HEIC 导入功能。这是我当前的流程:1)Matlab 调用 java 来执行 vips copy *.heic .ppm(我发现从 Matlab 直接调用 vips 需要很长时间才能读取 stdout),2)另一个 java 调用并行读取 stdout 缓冲区并将数据带回Matlab, 3) PPM格式用Matlab代码解析,RGB数据reshape成Matlab能理解的矩阵格式。你认为 Python 可以加快这个过程吗?
    • 一些附加信息:将上述过程的性能与流行图像格式的 Matlab 内置图像阅读器进行比较,结果我的libvips 包装器速度慢了 x1.5~x2.5。唯一的例外是.bmp,其中内置阅读器比我的包装器快 7 倍(嗯!)。也许我的方法不是最好的......
    【解决方案2】:

    不确定您是在寻找解决方法,还是希望 John 为 libvips 提供软件更新,或者究竟是什么。

    无论如何,我只想说,如果您想要将vips 输出转换为BMP 的解决方法,您可以使用ppmtobmp,它是NetPBM 套件的一部分。

    所以,对于一个文件:

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

    并且作为流过滤器,无需去磁盘:

    vips copy image.jpg .ppm | ppmtobmp | NextProcess
    

    请注意,ppm 格式实际上是 RGB,开头有 3-4 行 ASCII 标头,其中包含尺寸 - 试试看。所以,如果你能在 Windows 中找到删除 3-4 行 ASCII 的方法,你就可以得到 RGB。或者,如果您的图像是 3 字节/像素的 640x480 像素,也许您可​​以在 Windows 上找到一种方法来获取文件的最后 (640x480x3) 字节,或者以这种方式流式传输并丢弃 PPM 标头。

    关键字:HEIC、vips、NetPBM、BMP

    【讨论】:

    • 啊我总是忘记ppmtobmp,非常整洁。
    • 这两个解决方法是我一直在寻找的。我稍微修改了我的代码来操纵ppm 并从中提取RGB,它的效果非常好。我不知道ppm 是一种很容易解释的格式。用libvips 写ppm 也太快了!
    猜你喜欢
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    • 2018-08-21
    • 1970-01-01
    • 2013-05-01
    • 2020-07-27
    相关资源
    最近更新 更多