最初に少しコンテキスト。
私はカイロ(実際には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
私はただ夢を見ていますか?