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

时间:2017-10-02 22:19:16

标签: imagemagick pipe png bmp imagemagick-convert

我需要将来自chrome-headless的PNG转换为BMP 以使用它们,我还需要通过管道执行此操作而不将这些图像保存在某处。

Chrome设置为只将屏幕播放图像到stdout,这很好,但我似乎无法使用imagemagick转换工具来做我需要的。

使用

进行测试
cat foo.png | convert PNG:- BMP:-

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

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

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

如何转换为"覆盖"它通过stdin读取的每个文件的输出?

编辑:cat示例仅用于演示输入。最后的想法更像是

chrome-headless | *solution* | bmpreader

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

2 个答案:

答案 0 :(得分: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更容易。

答案 1 :(得分:0)

正如弗雷德(@ fmw42)所说,单独使用 ImageMagick 就无法做到这一点,但应该可以使用小型C / C ++,Perl,PHP或Python脚本执行某些操作。

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

因此,您可以编写一个脚本/程序,从管道中读取数据,获取块并将它们附加到内存中的字符串,并一直这样做,直到它到达IEND块。此时,它将使用 ImageMagick GD Pillow 将内存中的字符串转换为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

请注意,您的程序不必"了解" 所有块类型或其内容 - 只需识别块长度和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