显示动态图像变得越来越重要。GTK 4 将使 GTK 应用程序更容易显示动画;无论是程序化动画、webm 文件还是直播流。
一切皆可绘制
在查看动画之前,值得花一些时间了解 GTK 用于可绘制内容的底层抽象。在 GTK 2 和 3 中,主要是 GdkPixbuf:您加载一个文件,然后获得一个像素数据块(或多或少采用单一格式)。如果你想对其进行动画处理,可以使用 GdkPixbufAnimation,但可以公平地说它不是一个非常成功的 API。
GTK 4 引入了一个名为 GdkPaintable 的新 API,其灵感来自 CSS Houdini 项目。它非常灵活——任何可以合理绘制的东西都可以是一个 GdkPaintable。内容可以是可调整大小的(如 svg),或者随时间变化(如 webm)。
通常显示图像内容的 Widget,例如 GtkImage 或 GtkPicture 知道如何使用可绘制对象。过去以某种形式生成像素数据的许多东西现在可以表示为可绘制对象:纹理、图标,甚至是 Widget。
如果您有更专业的需求,可以使用 gtk_snapshot_to_paintable() 将 GtkSnapshot 中捕获的任何内容转换为可绘制对象。如果您创建了一个想要绘制可绘制对象的自定义 Widget,这非常简单。只需调用 gdk_paintable_snapshot()。
开始动画
正如我之前所说,可绘制对象可以随时间更改其内容。它们只需要发出 ::contents-changed 信号,GtkPicture 等 Widget 就会执行正确的操作并更新其显示。
那么,我们从哪里获得一个可以更改其内容的 GdkPaintable 呢?我们可以使用 GTK 4 的内置 GtkMediaFile API 从文件中加载它。这是一个高层 API,类似于 GstPlayer:您输入一个 URI,然后得到一个具有 play() 函数和 pause() 函数的对象,并且可以用作可绘制对象。
GTK 附带了 GtkMediaFile 的两个实现,一个使用 gstreamer,另一个使用 ffmpeg。由于我们不想让其中任何一个成为 GTK 的硬依赖项,它们都是可加载的模块。
您可以打开 GTK 检查器来找出正在使用的是哪个
保持控制
GtkMediaFile API 是 gtk4-widget-factory 在其首页上演示动画 GTK 徽标的方式
正如您所见,它不仅仅是一个移动的图片,还有媒体控件——您可以通过使用 GtkVideo Widget 免费获得这些控件。
超越基础
从文件中加载动画可能不是那么令人兴奋,所以这里有另一个 例子,它更进一步。这是一个周末小项目,它结合了 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);