Python 在PyGame(SDL)中使用Cairo时的字节顺序

Python 在PyGame(SDL)中使用Cairo时的字节顺序,python,sdl,pygame,cairo,pycairo,Python,Sdl,Pygame,Cairo,Pycairo,我目前有一些代码使用pycairo绘制,并通过PyGame渲染到SDL曲面。这在Linux和Windows上运行得很好,但Mac让我头疼。所有内容都是蓝色或粉色的,字节顺序似乎是BGRA而不是ARGB,我尝试使用pygame.Surface.set_掩码和set_移位,但都没有效果。这仅在mac(osx 10.6)上被破坏: 我可以通过数组切片或使用PIL来修复它,但这会降低我的帧速率。有没有办法就地或通过设置来实现这一点?在大量的头发撕裂后,我有一个解决方法,通过简单地反转阵列,不会对帧速率造

我目前有一些代码使用pycairo绘制,并通过PyGame渲染到SDL曲面。这在Linux和Windows上运行得很好,但Mac让我头疼。所有内容都是蓝色或粉色的,字节顺序似乎是BGRA而不是ARGB,我尝试使用pygame.Surface.set_掩码和set_移位,但都没有效果。这仅在mac(osx 10.6)上被破坏:


我可以通过数组切片或使用PIL来修复它,但这会降低我的帧速率。有没有办法就地或通过设置来实现这一点?

在大量的头发撕裂后,我有一个解决方法,通过简单地反转阵列,不会对帧速率造成太大的影响:

import cairo
import pygame

width = 300
height = 200

pygame.init()
pygame.fastevent.init()
clock = pygame.time.Clock()
sdl_surface = pygame.display.set_mode((width, height))

c_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
ctx = cairo.Context(c_surface)

while True:
    pygame.fastevent.get()
    clock.tick(30)
    ctx.rectangle(10, 10, 50, 50)
    ctx.set_source_rgba(1.0, 0.0, 0.0, 1.0)
    ctx.fill_preserve()

    dest = pygame.surfarray.pixels2d(sdl_surface)
    dest.data[:] = c_surface.get_data()[::-1]
    tmp = pygame.transform.flip(sdl_surface, True, True)
    sdl_surface.fill((0,0,0))    #workaround to clear the display
    del dest     #this is needed to unlock the display surface
    sdl_surface.blit(tmp, (0,0))
    pygame.display.flip()
事实上,我必须从一个临时表面上删除数组和blit,这似乎不正确,但这是翻转显示的唯一方法。如果有人在这里有更干净的建议,请评论

import cairo
import pygame

width = 300
height = 200

pygame.init()
pygame.fastevent.init()
clock = pygame.time.Clock()
sdl_surface = pygame.display.set_mode((width, height))

c_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
ctx = cairo.Context(c_surface)

while True:
    pygame.fastevent.get()
    clock.tick(30)
    ctx.rectangle(10, 10, 50, 50)
    ctx.set_source_rgba(1.0, 0.0, 0.0, 1.0)
    ctx.fill_preserve()

    dest = pygame.surfarray.pixels2d(sdl_surface)
    dest.data[:] = c_surface.get_data()[::-1]
    tmp = pygame.transform.flip(sdl_surface, True, True)
    sdl_surface.fill((0,0,0))    #workaround to clear the display
    del dest     #this is needed to unlock the display surface
    sdl_surface.blit(tmp, (0,0))
    pygame.display.flip()