使用 pygame 以编程方式创建和填充 8 位表面的最快方法
Fastest way to create and populate an 8-bit surface programatically with pygame
我需要通过列表数组以编程方式创建一个 8 位表面。这是我的一个约束。到目前为止,我已经使用了这个解决方案:
width = int(4)
height = int(4)
image_data_raw = ['\xf1', '\xf1', '\xf1', '\xf1',
'\xf1', '\x00', '\x00', '\xf1',
'\xf1', '\x00', '\x00', '\xf1',
'\xf1', '\xf1', '\xf1', '\xf1']
def make_surface_from_raw_data():
global image_data_raw
global width
global height
image_data_raw_bytes = [ord(i) for i in image_data_raw]
test_surface = pygame.Surface((width, height))
pxarray = pygame.PixelArray(test_surface)
i = int(0)
for y in range(height):
for x in range(width):
pxarray[x, y] = pygame.Color(image_data_raw_bytes[i],
image_data_raw_bytes[i],
image_data_raw_bytes[i])
i += 1
new_surface = pxarray[:, :].make_surface()
image_data_2d_surface = new_surface
return image_data_2d_surface
但是,我对它不满意,因为它太慢了。
我的 "image_raw_data" 将比 4x4 大得多,并从串行源流式传输。它们也总是 8 位灰度。因此,无需从8位转换为rbga。
我想知道是否有更快的方法来完成这个任务。在我的循环中,有几次从 char 到 8 位 int 然后到 rgba 的转换。
非常感谢。
如果您安装了 NumPy,使用类似的东西会快得多:
def make_surface_from_raw_data():
global image_data_raw
global width
global height
# we create a numpy array from image_data_raw
# and do some bit shifting so that the single value is used for each color channel
# then we have to reshape that array into the right size
data = np.fromiter((x | x << 8 | x << 16 for x in (ord(i) for i in image_data_raw)), dtype=np.uint32).reshape(width, -width)
# now let's create a Surface in the right dimension
# that's faster than letting pygame figure out the size from the array (with the make_surface function)
surface = pygame.Surface((width, height))
# blit_array is the fastet way to get the value of the array into the Surface
# (faster than creating an array from the Surface and updating it)
pygame.surfarray.blit_array(surface, data)
return surface
我需要通过列表数组以编程方式创建一个 8 位表面。这是我的一个约束。到目前为止,我已经使用了这个解决方案:
width = int(4)
height = int(4)
image_data_raw = ['\xf1', '\xf1', '\xf1', '\xf1',
'\xf1', '\x00', '\x00', '\xf1',
'\xf1', '\x00', '\x00', '\xf1',
'\xf1', '\xf1', '\xf1', '\xf1']
def make_surface_from_raw_data():
global image_data_raw
global width
global height
image_data_raw_bytes = [ord(i) for i in image_data_raw]
test_surface = pygame.Surface((width, height))
pxarray = pygame.PixelArray(test_surface)
i = int(0)
for y in range(height):
for x in range(width):
pxarray[x, y] = pygame.Color(image_data_raw_bytes[i],
image_data_raw_bytes[i],
image_data_raw_bytes[i])
i += 1
new_surface = pxarray[:, :].make_surface()
image_data_2d_surface = new_surface
return image_data_2d_surface
但是,我对它不满意,因为它太慢了。
我的 "image_raw_data" 将比 4x4 大得多,并从串行源流式传输。它们也总是 8 位灰度。因此,无需从8位转换为rbga。
我想知道是否有更快的方法来完成这个任务。在我的循环中,有几次从 char 到 8 位 int 然后到 rgba 的转换。
非常感谢。
如果您安装了 NumPy,使用类似的东西会快得多:
def make_surface_from_raw_data():
global image_data_raw
global width
global height
# we create a numpy array from image_data_raw
# and do some bit shifting so that the single value is used for each color channel
# then we have to reshape that array into the right size
data = np.fromiter((x | x << 8 | x << 16 for x in (ord(i) for i in image_data_raw)), dtype=np.uint32).reshape(width, -width)
# now let's create a Surface in the right dimension
# that's faster than letting pygame figure out the size from the array (with the make_surface function)
surface = pygame.Surface((width, height))
# blit_array is the fastet way to get the value of the array into the Surface
# (faster than creating an array from the Surface and updating it)
pygame.surfarray.blit_array(surface, data)
return surface