如何在GdkPixbuf.Pixbuf上渲染文本

2 投票
1 回答
1402 浏览
提问于 2025-04-18 14:55

我正在尝试使用Python和Gdk 3在一个Pixbuf上添加文本。

我在网上搜索了几个小时关于这个主题的信息,看来我需要从pixbuf创建一个cairo上下文。可惜我对cairo完全没有经验,但我还是拼凑出了这段代码:

from gi.repository import Gdk

def put_text(pixbuf, text, x, y):
    #create a Gdk.Window
    window_attr= Gdk.WindowAttr()
    window_attr.width= pixbuf.get_width()
    window_attr.height= pixbuf.get_height()
    window_attr.window_type= Gdk.WindowType.OFFSCREEN
    #~ window_attr.window_type= Gdk.WindowType.TEMP
    window_attr.redirect= True
    #~ window_attr.redirect= False
    window= Gdk.Window(None, window_attr, Gdk.WindowAttributesType(0))

    #make a cairo context from the window
    context= Gdk.cairo_create(window)
    Gdk.cairo_set_source_pixbuf(context, pixbuf, 0, 0)

    #render text
    context.move_to(x, y)
    context.set_font_size(15)
    context.show_text(text)

    #get the resulting pixbuf
    surface= context.get_target()
    result= Gdk.pixbuf_get_from_surface(surface, 0, 0, surface.get_width(), surface.get_height())

    #~ window.destroy()
    return result

这段代码至少没有让我程序崩溃。不过,它生成的pixbuf完全是透明的。有没有人能告诉我我哪里做错了,或者有没有更好的方法?

1 个回答

4

我终于写出了能运行的代码。看来使用 from gi.repository import cairo 是个大错误。

from gi.repository import Gdk
import cairo

def put_text(pixbuf, text, x, y):
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, pixbuf.get_width(), pixbuf.get_height())
    context = cairo.Context(surface)

    Gdk.cairo_set_source_pixbuf(context, pixbuf, 0, 0)
    context.paint() #paint the pixbuf

    #add the text
    fontsize= 20
    context.move_to(x, y+fontsize)
    context.set_font_size(fontsize)
    context.set_source_rgba(0,0,0,1)
    context.show_text(text)

    #get the resulting pixbuf
    surface= context.get_target()
    pixbuf= Gdk.pixbuf_get_from_surface(surface, 0, 0, surface.get_width(), surface.get_height())

    return pixbuf

撰写回答