首先是一些上下文。
我正在尝试使用 Cairo(实际上是 pycairo)绘制 Gdk(实际上是 pygtk)pixbuf。我的原始代码如下所示:
import cairo as C
import gtk.gdk as GG
FMT = C.FORMAT_ARGB32
CSP = GG.COLORSPACE_RGB
st = C.ImageSurface.format_stride_for_width(FMT, zw)
surf = C.ImageSurface(FMT, zw, zh)
c = C.Context(surf)
# draw into c here ...
pixels = surf.get_data()
return GG.pixbuf_new_from_data(pixels, CSP, True, 8, zw, zh, st)
有一段时间,看起来这只是工作,直到我尝试绘制颜色而不是黑色文本。事实证明,这两个库在字节顺序上存在分歧,如下所示:
# !!! FIXME !!! cairo ARGB surfaces and gdk pixbufs disagree on bytesex:
# cairo: LSB --> B G R A <-- MSB
# gdk: LSB --> R G B A <-- MSB
# !!! WTF !!!
结果是(从 pixbuf 传送到屏幕后)红色和蓝色通道交换的图像:-(
因此,如果我继续使用 pixbufs(如我所愿),我需要对数据进行后处理,每 1 个字节与每 3 个字节交换一次。我可以用普通的python做到这一点:
def changesex(data):
i0 = 0
i2 = 2
l = len(data)
while i2 < l:
temp = data[i0]
data[i0] = data[i2]
data[i2] = temp
i0 += 4
i2 += 4
但我认为如果有一个用 C 编写的内置运算符,使用 numpy 可能会更快。像这样:
a = np.frombuffer(data, dtype=np.uint8)
a.shape = (len(data) / 4, 4)
temp = a[:,0]
a[:,0] = a[:,2]
a[:,2] = temp
我只是在做梦吗?