Пиксельная прозрачность в PyGTK - PullRequest
1 голос
/ 10 июня 2009

Как я могу создать растровые изображения PyGTK с одним значением пикселя, установленным на прозрачное? Я знаю, что это что-то связано с созданием растрового изображения глубины 1 и установкой его в качестве маски, но я нахожу только то, что оно либо ничего не делает, либо полностью стирает мое растровое изображение при рисовании. На данный момент я делаю растровое изображение с

r = self.get_allocation()
p1 = gtk.gdk.Pixmap(self.window,r.width,r.height)
p1_c = p1.cairo_create()

затем нарисуйте черные линии по всему Каиру. То, что я хотел бы сделать, это сделать всю область, не покрытую линиями прозрачной (скажем, сделать белый цвет прозрачным цветом), чтобы при рисовании в окне с помощью draw_drawable все оставалось «под» неповрежденный.

Часто задаваемые вопросы и сообщения в рассылках по этой проблеме являются наиболее бесполезными, поскольку они настолько устарели. Кто-то должен знать здесь!

Ответы [ 2 ]

2 голосов
/ 15 июня 2009

Я не думаю, что вы можете делать то, что вы хотите, с Pixmap или Pixbuf, но вот две стратегии реализации каракулей поверх существующего Widget. Самый очевидный из них - это просто отловить событие рисования и нарисовать прямо на Widget Drawable без сохраненного изображения в середине:

from gtk import Window, Button, main
from math import pi
import cairo

w = Window()
b = Button("Draw on\ntop of me!")

def scribble_on(cr):
    cr.set_source_rgb(0, 0, 0)
    cr.rectangle(10, 10, 30, 30)
    cr.fill()
    cr.arc(50, 50, 10, 0, pi)
    cr.stroke()

def expose_handler(widget, event):
    cr = widget.window.cairo_create()
    cr.rectangle(event.area.x, event.area.y,
                 event.area.width, event.area.height)
    cr.clip()
    scribble_on(cr)
    return False

b.connect_after("expose_event", expose_handler)
w.add(b)
w.set_size_request(100, 100)
w.show_all()
main()

Второй вариант, если вы хотите иметь промежуточное ARGB-изображение, которое не нужно обновлять каждый раз, когда запрашивается перерисовка, - это предварительно отрендерить изображение до ImageSurface. Вот замена для expose_handler выше, которая рисует изображение только один раз:

import cairo
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 100, 100)
scribble_on(cairo.Context(surface))

def expose_image_handler(widget, event):
    cr = widget.window.cairo_create()
    cr.rectangle(event.area.x, event.area.y,
                 event.area.width, event.area.height)
    cr.clip()
    cr.set_source_surface(surface)
    cr.paint()

Если это именно то, что вам нужно, я бы порекомендовал обновить название вопроса, чтобы отразить ваши реальные потребности:).

1 голос
/ 10 июня 2009

Похоже, вы хотите использовать Pixbuf, а не Pixmap. Pixbuf включает альфа-настройку, которая даст вам прозрачность, а Pixmap - нет.

...