3

最初に少しコンテキスト。

私はカイロ(実際には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)

しばらくの間、黒のテキストではなく色を描画しようとするまでは、これでうまくいくように見えました。次のように、2つのライブラリがバイト順序で一致しないことがわかります。

# !!! 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

私はただ夢を見ていますか?

4

1 に答える 1

6

aの最初の(N,4)配列に注目すると、高度なインデックスを使用するだけで表現をB,G,R,A取得できます。(N,4)R,G,B,A

a = np.frombuffer(data, dtype=np.uint8)
a.shape = (-1, 4)
rearranged = a[:,[2,1,0,3]]
于 2012-10-03T08:04:24.340 に答える