【问题标题】:How to write image with palette information?如何使用调色板信息编写图像?
【发布时间】:2021-08-30 04:32:54
【问题描述】:

我想使用 Pillow 和/或 pypng 在 Python 中创建一个带有调色板信息的 PNG 图像文件。

输入是:

  1. 调色板信息

    [[0, 128, 0],
     [0, 64, 128],
     [0, 128, 128],
     [0, 64, 0],
     [0, 64, 64],
     [128, 128, 0],
     ...
    ]
    
  2. 输入图片 (numpy.ndarray)

    img = cv2.imread("myimage.png")
    print(img)
    
    [[[0, 128, 0],
      [0, 128, 0],
      [0, 128, 0],
      ...
     ]
     [[0, 128, 0],
      [0, 64, 64],
      [0, 64, 0],
      ...
     ]
    ]
    

而且,输出是:

image = PIL.Image.open("output.png")
image = np.array(image)
print(image)

[[0, 0, 0, 0, ..... 5, 5, 5]
 [0, 4, 3, 3, ..... 4, 4, 4]
  ...
]

输入图像和输出图像必须在视觉上相同,

PIL.Image.open读取输出图像并将其更改为NumPy数组后,应如上所示输出。

有没有办法做到这一点?

【问题讨论】:

    标签: python numpy image-processing python-imaging-library png


    【解决方案1】:

    这里有一些演示代码可以将现有的 RGB 图像转换为indexed color image。请记住,Pillow 仅允许在某些调色板中存储 256 种不同的颜色,参见。 Image.putpalette。因此,请确保您的输入图像包含的不同颜色不超过 256 种。

    另外,我假设调色板是已知的,并且现有 RGB 图像中的所有颜色都完全来自该调色板。否则,您需要添加代码以提取所有颜色,并事先设置适当的调色板。

    import cv2
    import numpy as np
    from PIL import Image
    
    # Existing palette as nested list
    palette = [
        [0, 128, 0],
        [0, 64, 128],
        [0, 128, 128],
        [0, 64, 0],
    ]
    
    # Existing RGB image, read with OpenCV (Attention: Correct color ordering)
    img = cv2.imread('myimage.png')
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    h, w = img.shape[:2]
    print(img)
    # [[[  0 128   0]
    #   [  0 128   0]
    #   [  0 128   0]
    #   ...
    #   [  0 128 128]
    #   [  0 128 128]
    #   [  0 128 128]]
    
    # Generate grayscale output image with replaced values
    img_pal = np.zeros((h, w), np.uint8)
    for i_p, p in enumerate(palette):
        img_pal[np.all(img == p, axis=2)] = i_p
    cv2.imwrite('output.png', img_pal)
    
    # Read grayscale image with Pillow
    img_pil = Image.open('output.png')
    print(np.array(img_pil))
    # [[0 0 0 ... 2 2 2]
    #  [0 0 0 ... 2 2 2]
    #  [0 0 0 ... 2 2 2]
    #  ...
    #  [1 1 1 ... 3 3 3]
    #  [1 1 1 ... 3 3 3]
    #  [1 1 1 ... 3 3 3]]
    
    # Convert to mode 'P', and apply palette as flat list
    img_pil = img_pil.convert('P')
    palette = [value for color in palette for value in color]
    img_pil.putpalette(palette)
    
    # Save indexed image for comparison
    img_pil.save('output_indexed.png')
    

    这是现有的RGB图像myimage.png

    那是中间的output.png——你很可能不会看到不同的深灰色、近乎黑色的颜色:

    为了比较,这是在转换为mode P 并应用调色板之后的索引彩色图像:

    ----------------------------------------
    System information
    ----------------------------------------
    Platform:      Windows-10-10.0.19041-SP0
    Python:        3.9.1
    PyCharm:       2021.1.1
    NumPy:         1.19.5
    OpenCV:        4.5.2
    Pillow:        8.2.0
    ----------------------------------------
    

    【讨论】:

      猜你喜欢
      • 2012-01-26
      • 1970-01-01
      • 2010-09-19
      • 1970-01-01
      • 2021-08-01
      • 2011-02-27
      • 1970-01-01
      • 2012-06-08
      • 2017-05-09
      相关资源
      最近更新 更多