代码之家  ›  专栏  ›  技术社区  ›  gmmo

用pygame编程创建和填充8位曲面的最快方法

  •  2
  • gmmo  · 技术社区  · 6 年前

    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
    

    但是,我不满意它,因为它太慢了。

    我想知道是否有更快的方法来完成这项任务。在我的循环中,有几个从char到8位int再到rgba的转换。

    非常感谢你。

    1 回复  |  直到 6 年前
        1
  •  1
  •   sloth    6 年前

    如果已安装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  
    
    推荐文章