显示动态图像变得越来越重要。GTK 4 将使 GTK 应用程序更容易显示动画;无论是程序动画、webm 文件还是直播流。
一切皆可绘制
在研究动画之前,值得花一点时间了解 GTK 用于可绘制内容的底层抽象。在 GTK 2 和 3 中,主要是 GdkPixbuf:您加载一个文件,并获得一个像素数据块(或多或少以单一格式)。如果你想为其制作动画,可以使用 GdkPixbufAnimation,但可以公平地说它不是一个非常成功的 API。
GTK 4 引入了一个名为 GdkPaintable 的新 API,其灵感来自 CSS Houdini 的努力。它非常灵活——任何你可以合理绘制的东西都可以是一个 GdkPaintable。内容可以是可调整大小的(如 svg),或随着时间而改变(如 webm)。
通常显示图像内容的窗口小部件,如 GtkImage 或 GtkPicture 知道如何使用可绘制对象。过去以某种形式生成像素数据的许多东西现在可以表示为可绘制对象:纹理、图标,甚至窗口小部件。
如果您有更专门的需求,任何可以在 GtkSnapshot 中捕获的内容都可以使用 gtk_snapshot_to_paintable() 转换为可绘制对象。如果您制作了一个想要绘制可绘制对象的自定义窗口小部件,那么这非常简单。只需调用 gdk_paintable_snapshot()。
开始动画
正如我之前所说,可绘制对象可以随着时间的推移改变其内容。它们只需要发出 ::contents-changed 信号,像 GtkPicture 这样的窗口小部件就会执行正确的操作并更新其显示。
那么,我们从哪里获得一个内容会发生变化的 GdkPaintable 呢?我们可以使用 GTK 4 的内置 GtkMediaFile api 从文件中加载它。这是一个高级 api,类似于 GstPlayer:你传入一个 uri,你会得到一个具有 play() 函数和 pause() 函数的对象,并且可以作为可绘制对象工作。
GTK 附带了 GtkMediaFile 的两个实现,一个使用 gstreamer,另一个使用 ffmpeg。由于我们不想让这两个成为 GTK 的硬性依赖,它们是可加载的模块。
您可以打开 GTK 检查器来找出正在使用的是哪个
保持控制
GtkMediaFile API 是 gtk4-widget-factory 在其首页上演示动画 GTK 徽标时所使用的。
正如你所看到的,它不仅仅是一个移动的图片,那里也有媒体控件——通过使用 GtkVideo 窗口小部件,你可以免费获得这些。
超越基础
从文件中加载动画可能不是那么令人兴奋,所以这里有另一个示例,它更进一步。这是一个结合了 GtkVideo、libportal 和 pipewire 的小周末项目,演示如何在 GTK 应用程序中显示视频流。
坏消息是,我们还没有找到支持胶水代码的永久位置(一个 GstSink、一个 GdkPaintable 和一个 GtkMediaStream)。它不适合 GTK,因为如前所述,我们不想依赖 gstreamer,而且它不适合 gstreamer,因为 GTK 4 尚未发布。我们肯定会在不久的将来解决这个问题,因为将 gstreamer 管道转换为几行代码的可绘制对象非常方便。
好消息是,代码的核心只有几行
fd = xdp_portal_open_pipewire_remote_for_camera (portal); stream = gtk_gst_media_stream_new_for_pipewire_fd (fd, NULL); gtk_video_set_media_stream (video, stream);