Как быстрее всего нарисовать изображение в Gtk+?

У меня есть изображение/pixbuf, которое я хочу нарисовать в gtk.DrawingArea и часто обновлять, поэтому операция копирования должна быть быстрой. Делаем это простым способом:

def __init__(self):
  self.drawing_area = gtk.DrawingArea()
  self.image = gtk.gdk.pixbuf_new_from_file("image.png")

def area_expose_cb(self, area, event):
  self.drawing_area.window.draw_pixbuf(self.gc, self.image, 0, 0, x, y)

Однако это приводит к очень низкой производительности, вероятно, из-за того, что pixbuf не находится в цветовом формате дисплея.

У меня также не было успеха с Cairo, поскольку он кажется ограниченным 24/32-битными форматами и не имеет 16-битного формата (FORMAT_RGB16_565 не поддерживается и устарел).

Какие есть альтернативы быстрому рисованию картинок в Gtk+?


person Grumbel    schedule 06.06.2009    source источник


Ответы (3)


Попробуйте создать растровое изображение, использующее ту же цветовую карту, что и ваша область рисования.

dr_area.realize()
self.gc = dr_area.get_style().fg_gc[gtk.STATE_NORMAL]
img = gtk.gdk.pixbuf_new_from_file("image.png")
self.image = gtk.gdk.Pixmap(dr_area.window, img.get_width(), img.get_height())
self.image.draw_pixbuf(self.gc, img, 0, 0, 0, 0)

и рисование его на экране с помощью

dr_area.window.draw_drawable(self.gc, self.image, 0, 0, x, y, *self.image.get_size())
person Ivan Baldin    schedule 07.06.2009

Вы действительно не генерируете достаточную скорость/пропускную способность? Или вы просто видите мерцание?

Если это последнее, возможно, вам следует исследовать двойную буферизацию вместо выполнения ваших обновлений? По сути, идея состоит в том, чтобы рисовать в невидимый буфер, а затем указывать графической карте использовать новый буфер.

Можете заглянуть на эту страницу, на которой есть информация о двойной буферизации.

person Chris Harris    schedule 06.06.2009
comment
Это пропускная способность, не мерцающая. Я пытаюсь сделать интерактивную полноэкранную прокрутку / анимацию на OLPC, который не очень быстро запускается, имеет довольно большой экран и работает в 16-битном режиме. То же самое в SDL работает без проблем. Использование gtk.Layout и его использование для прокрутки достаточно быстро, но выполнение прокрутки вручную путем рисования в gtk.DrawingArea (поскольку я мог бы добавить больше эффектов позже) совершенно непригодно для использования медленно. - person Grumbel; 07.06.2009

Возможно, стоит провести сравнительный анализ — если вы рисуете небольшой областью, она все еще медленная?

Если это так, возможно, стоит спросить в списках рассылки pygtk или gtk...

person Stuart Axon    schedule 17.08.2009