【问题标题】:How to display an image in Pygame using list of RGBA values of a image [duplicate]如何使用图像的 RGBA 值列表在 Pygame 中显示图像 [重复]
【发布时间】:2021-10-17 20:47:41
【问题描述】:

我正在尝试制作一个涉及一些图像的 pygame 项目。在这些图像中,有些非常相似,只是颜色发生了变化。所以我想出了为什么不只使用一张图像并使用 Python from this article 更改其对应颜色的想法。

from PIL import Image
import pygame as pg

img = Image.open("Assets/image.png")
img = img.convert("RGBA")
d = img.getdata()
new_image = []
for item in d:
    if item[:3] == (0,0,0):
        new_image.append((255,255,255,0))
    if item[:3] == (23,186,255):
        new_image.append((255,38,49,item[3]))
    else:
        new_image.append(item)
img.putdata(new_image)
img.save("a.png","PNG")

但在上面代码的最后两行中,它保存了图像,我不希望这样!
我想在 Pygame 代码中使用它来显示,然后当程序退出时,图像就消失了。那么如何使用 RGBA 值列表new _image 在 Pygame 中显示图像。
任何帮助将不胜感激。

【问题讨论】:

    标签: python pygame python-imaging-library


    【解决方案1】:

    使用pygame.image.frombuffer() 创建pygame.Surface。但是,您必须将列表转换为字节数组。使用ctypes 模块从列表中创建一个字节数组:

    flat_list = [e for c in new_image for e in c]
    bute_array = (ctypes.c_ubyte * len(flat_list))(*flat_list)
    surf = pg.image.frombuffer(bute_array, img.size, img.mode).convert_alpha()
    

    另见PIL and pygame.image

    请注意,您的算法存在错误。在中间情况下,您需要使用elif 而不是 if

    if item[:3] == (0,0,0):
        new_image.append((255,255,255,0))
    
    #if item[:3] == (23,186,255):
    elif item[:3] == (23,186,255):              # <---
    
        new_image.append((255,38,49,item[3]))
    else:
        new_image.append(item)
    

    注意:如果要将背景更改为白色,则需要使颜色不透明:

    new_image.append((255,255,255,0))

    new_image.append((255, 255, 255, 255))
    

    小例子:

    左图是测试图,右图是结果:

    from PIL import Image
    import pygame as pg
    import ctypes
    
    img = Image.open("Assets/image.png")
    img = img.convert("RGBA")
    d = img.getdata()
    new_image = []
    for item in d:
        if item[:3] == (0, 0, 0):
            new_image.append((255, 255, 255, 0))
            #new_image.append((255, 255, 255, 255))
        elif item[:3] == (23, 186, 255):
            new_image.append((255, 38, 49, item[3]))
        else:
            new_image.append(item)
    
    pg.init()
    window = pg.display.set_mode(img.size)
    
    flat_list = [e for c in new_image for e in c]
    bute_array = (ctypes.c_ubyte * len(flat_list))(*flat_list)
    surf = pg.image.frombuffer(bute_array, img.size, img.mode).convert_alpha()
    
    run = True
    while run:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                run = False 
    
        window.fill(0)
        window.blit(surf, (0, 0))
        pg.display.flip()
    
    pg.quit()
    

    旁注:

    您不需要使用 PLI 加载图像,您可以直接访问 pygame.Surface 的像素。有不同的选择:

    【讨论】:

    • @Rabbid76 感谢您的回答。我已经测试过它也适用于您所说的错误似乎是错误但不是错误我想将蓝色 (23,186,255) 更改为红色 (255,38,49) 并且我想让背景 (0,0,0) 透明。还要感谢您的旁注,我会尝试那个。 :)
    【解决方案2】:

    我可能完全错过了您的问题的重点,但据我了解,您想要加载图像并更改一些颜色。我会这样做:

    #!/usr/bin/env python3
    
    from PIL import Image
    import pygame as pg
    import numpy as np
    
    # Open image and ensure RGBA mode, not palette image
    img = Image.open("image.png").convert('RGBA')
    
    # Define some colours for readability
    black = [0,0,0]
    white = [255,255,255]
    red   = [255,0,0]
    blue  = [0,0,255]
    
    # Make image into Numpy array for vectorised processing
    na  = np.array(img)
    
    # Make re-usable mask of black pixels then change them to white
    mBlack = np.all(na[...,:3] == black, axis=-1)
    na[mBlack,:3] = white
    # Make re-usable mask of red pixels then change them to blue
    mRed  = np.all(na[...,:3] == red, axis=-1)
    na[mRed,:3] = blue
    
    pg.init()
    window = pg.display.set_mode(img.size)
    
    surf = pg.image.frombuffer(na.tobytes(), img.size, img.mode)
    
    run = True
    while run:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                run = False
    
        window.fill(0)
        window.blit(surf, (0, 0))
        pg.display.flip()
    
    pg.quit()
    

    这张图片是什么原因造成的:

    显示如下:

    所以你可以看到我制作的面具的力量,你可以这样做:

    # Make any pixels that were either red or black become magenta
    na[mRed|mBlack,:3] = [255,0,255]
    

    或者:

    # Make all pixels that were not black into cyan
    na[~mBlack,:3] = [0,255,255]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-18
      相关资源
      最近更新 更多