交换numpy数组的子数组

时间:2012-10-02 22:57:33

标签: python numpy pygtk pycairo

首先介绍一下。

我正在尝试用开罗绘制一个Gdk(实际上是pygtk)pixbuf (实际上是pycairo)。我原来的代码看起来像这样:

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到屏幕的blitting之后)一个图像 交换红色和蓝色通道: - (

所以,如果我继续使用pixbuf(我想要),我需要对数据进行后期处理, 每隔3个交换每个第1个字节。我可以用普通的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

但我认为如果有内置的话,使用numpy可能会更快 用C语言编写的运算符。像这样:

a = np.frombuffer(data, dtype=np.uint8)
a.shape = (len(data) / 4, 4)
temp = a[:,0]
a[:,0] = a[:,2]
a[:,2] = temp

我只是在做梦吗?

1 个答案:

答案 0 :(得分:6)

注意a (N,4) B,G,R,A的{​​{1}}数组,您可以获得(N,4)代表R,G,B,A,而不仅仅是使用一些高级索引:

a = np.frombuffer(data, dtype=np.uint8)
a.shape = (-1, 4)
rearranged = a[:,[2,1,0,3]]