Сначала немного контекста.
Я пытаюсь рисовать в Gdk (на самом деле pygtk) pixbuf с Cairo (на самом деле 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 на экран) изображение с поменявшимися местами красного и синего каналов :-(
Итак, если я продолжаю использовать pixbufs (как я хочу), мне нужно выполнить постобработку данных, заменяя каждый 1-й байт каждым 3-м. Я могу сделать это на простом питоне:
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
Я просто мечтаю?