首页 文章

将多个png转换为从stdin到stdout的bmps

提问于
浏览
0

我需要 convert PNGs coming from chrome-headless to BMPs 与他们合作,我也需要这样做 through pipes 而不保存那些图像 .

Chrome设置为只将屏幕播放图像到stdout,这工作正常,但我似乎无法获得imagemagick转换工具,我需要什么 .

在测试时

cat foo.png | convert PNG:- BMP:-

似乎使用一个输入图像(输出以'BM'开头,表示BMP二进制垃圾),

cat foo.png bar.png | convert PNG:- BMP:-

也只返回一个图像,这似乎是第一个 .

How can I get convert to "overwrite" the output for each file it reads through stdin?


编辑:猫的例子只是为了演示输入 . 最后的想法更像是

chrome-headless | *solution* | bmpreader

正如fmw42和Mark指出的那样,这似乎不可能与imagemagick开箱即用 .

2 回答

  • 0

    正如Fred(@ fmw42)所说,单独使用 ImageMagick 不能这样做,但应该可以用小的C / C,Perl,PHP或Python脚本做一些事情 .

    基本上,PNG文件很好"chunked",请参阅Wikipedia PNG Specification,每个块都有一个类型 - 例如 IHDR ( Headers ), PLTE (调色板), IDAT (图像数据), IEND (文件结束标记),最重要的是,长度为字节 .

    因此,您可以编写一个脚本/程序,从管道中读取数据,获取块并将它们附加到内存中的字符串,并一直这样做,直到它到达 IEND 块 . 此时,它将使用 ImageMagickGDPillow 将内存中的字符串转换为BMP并将其写入另一个管道,或将该字符串写入 ImageMagick 正在读取的管道,并让 ImageMagick 转换该文件 . 然后,您将把累积的(PNG)字符串清零并开始读取下一个文件 .

    我不喜欢编写和调试所有15点,但它看起来像这样:

    chrome-cast | demultiplex
    

    demultiplex 会是这样的:

    while not error
       clear accumulated string of PNG data
       done = false
       while not done
          read chunk type and length of chunk
          read whole chunk and append to accumulated string of PNG data
          if chunk = IEND
             pass accumulated PNG string to ImageMagick to make BMP
             done = true
          endif
       end
    end
    

    请注意,您的程序不需要"understand"所有块类型或其内容 - 只需识别块长度和 IEND 块到达时 .


    请注意,您可能希望运行 pngcheckpngsplit 以开始了解如何以块的形式构建PNG文件 - 它们是here . 事实上, pngsplit 可能会做你想要的 .

    以下是 pngcheck 的示例:

    pngcheck -v file.png
    
    File: file.png (462308 bytes)
      chunk IHDR at offset 0x0000c, length 13
        800 x 468 image, 32-bit RGB+alpha, non-interlaced
      chunk gAMA at offset 0x00025, length 4: 0.45455
      chunk cHRM at offset 0x00035, length 32
        White x = 0.3127 y = 0.329,  Red x = 0.64 y = 0.33
        Green x = 0.3 y = 0.6,  Blue x = 0.15 y = 0.06
      chunk bKGD at offset 0x00061, length 6
        red = 0x00ff, green = 0x00ff, blue = 0x00ff
      chunk pHYs at offset 0x00073, length 9: 3779x3779 pixels/meter (96 dpi)
      chunk tIME at offset 0x00088, length 7:  2 Oct 2017 21:34:26 UTC
      chunk IDAT at offset 0x0009b, length 32768
        zlib: deflated, 32K window, maximum compression
      chunk IDAT at offset 0x080a7, length 32768
      chunk IDAT at offset 0x100b3, length 32768
      chunk IDAT at offset 0x180bf, length 32768
      chunk IDAT at offset 0x200cb, length 32768
      chunk IDAT at offset 0x280d7, length 32768
      chunk IDAT at offset 0x300e3, length 32768
      chunk IDAT at offset 0x380ef, length 32768
      chunk IDAT at offset 0x400fb, length 32768
      chunk IDAT at offset 0x48107, length 32768
      chunk IDAT at offset 0x50113, length 32768
      chunk IDAT at offset 0x5811f, length 32768
      chunk IDAT at offset 0x6012b, length 32768
      chunk IDAT at offset 0x68137, length 32768
      chunk IDAT at offset 0x70143, length 3115
      chunk tEXt at offset 0x70d7a, length 37, keyword: date:create
      chunk tEXt at offset 0x70dab, length 37, keyword: date:modify
      chunk IEND at offset 0x70ddc, length 0
    No errors detected in file.png (24 chunks, 69.1% compression).
    

    我在Perl中做了一个基本的PNG分块版本,以获得另一个答案,所以快速查看here .

  • 0

    我不认为你可以用一次有多个图像的管道做到这一点 . 你可以遍历每个png图像并使用你的管道 . 管道将保持图像显示png后缀,但实际上将是bmp文件 . 但这似乎让我感到困惑 .

    在Imagemagick中,如果要将文件夹从一种格式转换为另一种格式,那么您应该只使用mogrify . 假设您的图像位于folder1中,并且您希望将它们保存到已存在的folder2中 . 然后你可以将目录更改为folder1然后执行:

    mogrify -format bmp -path path2/folder2 *.png
    

    这将保留输入名称,但在转换为该后缀类型时更改后缀 .

    转换只能有一个输出名称,可能与您的一个输入相同 . 它无法写入多个输出名称 . 如果输出格式支持图层或页面,那么输出将具有带图层/页面的一个名称,否则它将是XXX-1.bmp ... XXX-n.bmp其中XXX是通过执行的输出名称

    convert image1.png image2.png ... imageN.png newimage.suffix
    

    但是,您可以在脚本循环中执行此操作 . 但是mogrify更容易 .

相关问题