shape
属性是
numpy.array
中每个维度的元素数量。第一个元素是高度,第二个元素是宽度,第三个元素是通道数。
可以通过
pygame.image.frombuffer
生成一个
pygame.Surface
。第一个参数可以是一个
numpy.array
,第二个参数是格式(
RGB
或
RGBA
)。
通过切片获取
pygame.Surface
对象的尺寸(
宽度,
高度)。
size = cvImage.shape[1::-1]
根据第三通道确定
pygame.Surface
对象的目标格式。
format = 'RGBA' if cvImage.shape[2] == 4 else 'RGB'
由于源格式为BGR或BGRA,但目标格式为RGB或RGBA,因此需要交换红色和蓝色通道。
cvImage[:, :, [0, 2]] = cvImage[:, :, [2, 0]]
在灰度图像的情况下,必须使用
numpy.reshape
来改变数组的形状,并使用
numpy.repeat
将灰色通道扩展为红绿蓝三个颜色通道:
cvImage = np.repeat(cvImage.reshape(size[1], size[0], 1), 3, axis = 2)
使用他的数据,可以通过
pygame.image.frombuffer
生成
pygame.Surface
对象。
surface = pygame.image.frombuffer(cvImage.flatten(), size, format)
为了确保图像具有与显示表面相同的像素格式,并获得最佳性能,应使用
convert
或
convert_alpha
将表面转换为所需格式。
surface = surface.convert_alpha() if format == 'RGBA' else surface.convert()
完整的函数
cvImageToSurface
的功能:
def c2ImageToSurface(cvImage):
if cvImage.dtype.name == 'uint16':
cvImage = (cvImage / 256).astype('uint8')
size = cvImage.shape[1::-1]
if len(cvImage.shape) == 2:
cvImage = np.repeat(cvImage.reshape(size[1], size[0], 1), 3, axis = 2)
format = 'RGB'
else:
format = 'RGBA' if cvImage.shape[2] == 4 else 'RGB'
cvImage[:, :, [0, 2]] = cvImage[:, :, [2, 0]]
surface = pygame.image.frombuffer(cvImage.flatten(), size, format)
return surface.convert_alpha() if format == 'RGBA' else surface.convert()
简单示例:
![](https://istack.dev59.com/J5itT.webp)
import os
import pygame
import cv2 as cv
import numpy as np
def cvImageToSurface(cvImage):
if cvImage.dtype.name == 'uint16':
cvImage = (cvImage / 256).astype('uint8')
size = cvImage.shape[1::-1]
if len(cvImage.shape) == 2:
cvImage = np.repeat(cvImage.reshape(size[1], size[0], 1), 3, axis = 2)
format = 'RGB'
else:
format = 'RGBA' if cvImage.shape[2] == 4 else 'RGB'
cvImage[:, :, [0, 2]] = cvImage[:, :, [2, 0]]
surface = pygame.image.frombuffer(cvImage.flatten(), size, format)
return surface.convert_alpha() if format == 'RGBA' else surface.convert()
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
cvImage1 = cv.imread('woodtiles.jpg', cv.IMREAD_GRAYSCALE)
cvImage2 = cv.imread('woodtiles.jpg', cv.IMREAD_UNCHANGED)
cvImage3 = cv.imread('Apple1-256.png', cv.IMREAD_UNCHANGED)
pygameSurface1 = cvImageToSurface(cvImage1)
pygameSurface2 = cvImageToSurface(cvImage2)
pygameSurface3 = cvImageToSurface(cvImage3)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill(0)
window.blit(pygameSurface1, pygameSurface1.get_rect(topleft = window.get_rect().inflate(-10, -10).topleft))
window.blit(pygameSurface2, pygameSurface2.get_rect(center = window.get_rect().center))
window.blit(pygameSurface3, pygameSurface3.get_rect(bottomright = window.get_rect().inflate(-10, -10).bottomright))
pygame.display.flip()
pygame.quit()