【问题标题】:Saving an Image stored in BytesIO in pillow将存储在 BytesIO 中的图像保存在枕头中
【发布时间】:2020-05-06 16:57:35
【问题描述】:

我有一个存储为 Pillow 的 BytesIO 的图像,我需要将它保存到一个包含一些标题信息(包含文本属性)的文件中,我需要针对我的问题添加这些信息。我需要根据某种图像压缩格式来表示字节。那可能吗?如果是,怎么做? 我还需要在文件中存储多个图像。

【问题讨论】:

    标签: python-imaging-library image-compression


    【解决方案1】:

    在一个文件中存储多个图像对于 PNG、JPEG 和大多数常见格式是有问题的。一种选择是 TIFF - 不确定这是否适合您?

    以下是至少可以在 PNG 中存储一些附加文本的方法:

    #!/usr/bin/env python3
    
    from PIL.PngImagePlugin import Image, PngInfo
    
    # Create empty metadata and add a couple of text strings
    metadata = PngInfo()
    metadata.add_text("Key1:","Value1")
    metadata.add_text("Key2:","Value2")
    
    # Create red image and save with metadata embedded
    im = Image.new('RGB',(64,64),'red')
    im.save("result.png", pnginfo=metadata)
    

    如果您使用pngcheck 进行检查,您将看到:

    pngcheck -7v result.png
    

    样本输出

    File: result.png (200 bytes)
      chunk IHDR at offset 0x0000c, length 13
        64 x 64 image, 24-bit RGB, non-interlaced
      chunk tEXt at offset 0x00025, length 12, keyword: Key1:
        Value1
      chunk tEXt at offset 0x0003d, length 12, keyword: Key2:
        Value2
      chunk IDAT at offset 0x00055, length 95
        zlib: deflated, 32K window, default compression
      chunk IEND at offset 0x000c0, length 0
    No errors detected in result.png (5 chunks, 98.4% compression).
    

    以下是在单个 TIFF 文件中保存 3 张图像和一条评论的方法:

    from PIL import Image 
    from PIL.TiffImagePlugin import ImageFileDirectory_v2, TiffTags 
    
    # Create a structure to hold meta-data
    ifd = ImageFileDirectory_v2() 
    ifd[270] = 'Some Funky Comment' 
    ifd.tagtype[270] = TiffTags.ASCII 
    
    # Create red image and save with metadata embedded 
    im1 = Image.new('RGB',(50,50),'red') 
    im2 = Image.new('RGB',(64,64),'green') 
    im3 = Image.new('RGB',(80,80),'blue') 
    im1.save("result.tif", append_images[im2,im3], save_all=True, tiffinfo=ifd)
    

    并检查:

    tiffinfo -v result.tif
    

    样本输出

    TIFF Directory at offset 0x8 (8)
      Image Width: 50 Image Length: 50
      Bits/Sample: 8
      Compression Scheme: None
      Photometric Interpretation: RGB color
      Samples/Pixel: 3
      Rows/Strip: 50
      Planar Configuration: single image plane
      ImageDescription: Some Funky Comment
    TIFF Directory at offset 0x1e08 (7688)
      Image Width: 64 Image Length: 64
      Bits/Sample: 8
      Compression Scheme: None
      Photometric Interpretation: RGB color
      Samples/Pixel: 3
      Rows/Strip: 64
      Planar Configuration: single image plane
      ImageDescription: Some Funky Comment
    TIFF Directory at offset 0x4eb8 (20152)
      Image Width: 80 Image Length: 80
      Bits/Sample: 8
      Compression Scheme: None
      Photometric Interpretation: RGB color
      Samples/Pixel: 3
      Rows/Strip: 80
      Planar Configuration: single image plane
      ImageDescription: Some Funky Comment
    


    然后您可以像这样使用 ImageMagick 在命令行中提取图像。

    提取第一张图片:

    magick result.tif[0] first.png
    

    提取最后一张图片:

    magick result.tif[-1] last.png
    

    提取所有三个图像:

    magick result.tif image-%d.png
    

    结果

    -rw-r--r--  1 mark  staff  457 21 Jan 08:11 image-0.png
    -rw-r--r--  1 mark  staff  458 21 Jan 08:11 image-1.png
    -rw-r--r--  1 mark  staff  460 21 Jan 08:11 image-2.png 
    

    注意:如果您运行的是 v6 ImageMagick,请使用 convert 代替上面的 magick

    关键字:Python、PIL、图像处理、多张图像、TIF、评论、tiffinfo、IFD、PNG tEXt。

    【讨论】:

    • 以后,我会在我所有的图片中添加时髦的 cmets。 :-)
    • @HansHirse 很好 - 拥有时髦的 cmets 非常重要,因为它们在抓取(搜索)文件时很容易被发现 :-) 而 comment=comment 有点无聊 :-)
    • @MarkSetchell 感谢您的出色而全面的回答。我想使用正常的二进制写入来存储 ByteIO,因为我认为这些字节表示压缩图像。我的目标是有一个带有文本、字母数字参数的标题。不确定将我的应用程序的标头作为 cmets 存储在文件中是否是一个好主意,更不用说我还在考虑对文本实施一些文本压缩方法。不确定 TIFF 是否会在这种情况下发挥作用,您怎么看?我看到OpenCV的imencode提供了压缩格式,我得去看看。
    • 图片的开头不能有文本和内容的标题。图像查看器使用前几个字节来检测图像类型、高度和宽度。将二进制图像数据与文本数据存储在同一文件中通常不是最好的主意。也许尝试更清楚地了解您实际想要存储的内容以及为什么需要将其放在单个文件中。也许您可以将几个图像文件和一个文本文件放在一个压缩存档中?
    • TIFF ImageFileDirectory_v2 示例中的幻数 270 来自哪里?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    • 2018-04-28
    • 2015-10-10
    相关资源
    最近更新 更多