pygame.surfarray.pixels3d 没有为文本表面提供正确的像素值

pygame.surfarray.pixels3d doesn’t give correct pixel values with a text surface

所以,我试图让一些文本占据所有像素,但我意识到 pygame.surfarray.pixels3d 没有给出预期的输出。

这是我尝试过的:

import pygame
# import numpy as np
pygame.init()

width, height = 800, 800
win = pygame.display.set_mode((width, height))


font = pygame.font.SysFont("Monospace", 100, True)
text = font.render("test", True, (255, 255, 255))


# saves the correct image with text
pygame.image.save(text,"image.png")

# gives all (255,255,255)?!
pixels = pygame.surfarray.pixels3d(text).copy()

# remake surface from these pixels - doesn’t give the text.
text = pygame.surfarray.make_surface(pixels)
text_rect = text.get_rect(center=(width // 2, height // 2))



def main():
    run = True
    win.fill((0, 0, 0))
    win.blit(text, text_rect)
   
    pygame.display.update()

    while run:
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                run = False
                break

        


if __name__ == "__main__":
    main()


pygame.surfarray.pixels3d 适用于其他表面,所以我不明白这是 pygame 中的错误还是我做错了什么?

提前致谢。

编辑:

我也尝试过使用 surfarray.array3d,但没有成功。

你只读了Surface的颜色通道也有alpha通道。获取颜色通道 (array3d or pixels3d) and the alpha channel (array_alpha or pixels_alpha) and stick them together. Recreate the Surface with pygame.image.frombuffer:

pixels_rgb = pygame.surfarray.array3d(text)
pixels_alpha = pygame.surfarray.array_alpha(text).reshape((*pixels_rgb.shape[0:2], 1))
pixels_rgba = np.concatenate((pixels_rgb, pixels_alpha), 2)

text = pygame.image.frombuffer(pixels_rgba.transpose((1, 0, 2)).copy(order='C'), text.get_size(), 'RGBA')

或者,您可以创建具有不透明黑色背景的文本。设置黑色键 (set_colorkey) and convert it with convert_alpha:

text = font.render("test", True, (255, 255, 255), (0, 0, 0))
text.set_colorkey(0)
text = text.convert_alpha()

完整代码

import pygame
import numpy as np
pygame.init()

width, height = 800, 800
win = pygame.display.set_mode((width, height))

font = pygame.font.SysFont("Monospace", 100, True)

text1 = font.render("test 1", True, (255, 255, 255))
text2 = font.render("test 2", True, (255, 255, 255), (0, 0, 0))
text2.set_colorkey(0)
text2 = text2.convert_alpha()

pixels_rgb = pygame.surfarray.array3d(text1)
pixels_alpha = pygame.surfarray.array_alpha(text1).reshape((*pixels_rgb.shape[0:2], 1))
pixels_rgba = np.concatenate((pixels_rgb, pixels_alpha), 2)
text1 = pygame.image.frombuffer(pixels_rgba.transpose((1, 0, 2)).copy(order='C'), text1.get_size(), 'RGBA')

pixels = pygame.surfarray.pixels3d(text2).copy()
text2 = pygame.surfarray.make_surface(pixels)

text1_rect = text1.get_rect(center=(width // 2, height // 2 - 50))
text2_rect = text1.get_rect(center=(width // 2, height // 2 + 50))

def main():
    run = True
    win.fill((0, 0, 0))
    win.blit(text1, text1_rect)
    win.blit(text2, text2_rect)
    pygame.display.update()
    while run:
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                run = False

if __name__ == "__main__":
    main()