【问题标题】:The easiest way of drawing an array of pixels in GTK 4.0 in C在 C 的 GTK 4.0 中绘制像素数组的最简单方法
【发布时间】:2022-12-10 12:56:11
【问题描述】:

我正在尝试从现有的内存缓冲区中找到一个在 GTK 4.0 中显示图像的示例,其中图像以大小为浮点数组的形式存储宽 x 高 x 3.我知道我需要使用 GtkImage,但我不知道如何将这样的数组传递给它。

只是为了上下文,我想实现一个渲染一些图像的原型,它们都在内存中渲染,结果,我有一个这样的浮点数数组,每个像素三个浮点数。不幸的是,我找不到最新的 GTK 4.0 的任何示例。有很多从磁盘加载图像的例子,但对我来说这似乎是在跳过不必要的环节。我过去常常将它们作为 OpenGL 纹理加载并在四边形上显示它们,但它看起来也像是用大锤钉钉子。

预先感谢您的任何帮助!

【问题讨论】:

标签: c gtk4


【解决方案1】:

您可以使用 GdkMemoryTexture 来存储内存中的图像,并使用 GtkPicture 来绘制它。以下是创建不透明的 8 位 RGB 图像并将其显示在屏幕上的示例:

/* pixel.c
 *
 * Compile: cc -ggdb pixel.c -o pixel $(pkg-config --cflags --libs gtk4) -o pixel
 * Run: ./pixel
 *
 * Author: Mohammed Sadiq <www.sadiqpk.org>
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later OR CC0-1.0
 */

#include <gtk/gtk.h>

#define BYTES_PER_R8G8B8 3
#define WIDTH  400

static void
fill_row (GByteArray *array,
          guint8      value,
          int         row_size)
{
  guint i;

  for (i = 0; i < row_size; i++) {
    /* Fill the same values for RGB */
    g_byte_array_append (array, &value, 1); /* R */
    g_byte_array_append (array, &value, 1); /* G */
    g_byte_array_append (array, &value, 1); /* B */
  }
}

static void
add_pixel_picture (GtkPicture *picture)
{
  g_autoptr(GBytes) bytes = NULL;
  GdkTexture *texture;
  GByteArray *pixels;
  gsize height;
  guint8 value;

  /* Draw something interesting */
  pixels = g_byte_array_new ();
  for (guint i = 0; i <= 0xff ; i++)
    fill_row (pixels, i, WIDTH);

  for (guint i = 0; i <= 0xff; i++)
    fill_row (pixels, 0xff - i, WIDTH);

  height = pixels->len / (WIDTH * BYTES_PER_R8G8B8);
  bytes = g_byte_array_free_to_bytes (pixels);

  texture = gdk_memory_texture_new (WIDTH, height,
                                    GDK_MEMORY_R8G8B8,
                                    bytes,
                                    WIDTH * BYTES_PER_R8G8B8);
  gtk_picture_set_paintable (picture, GDK_PAINTABLE (texture));
}

static void
app_activated_cb (GtkApplication *app)
{
  GtkWindow *window;
  GtkWidget *picture;

  window = GTK_WINDOW (gtk_application_window_new (app));
  g_object_set (window,
                "width-request", 500,
                "height-request", 400,
                NULL);
  picture = gtk_picture_new ();
  gtk_widget_add_css_class (picture, "frame");
  g_object_set (picture,
                "margin-start", 96,
                "margin-end", 96,
                "margin-top", 96,
                "margin-bottom", 96,
                NULL);

  gtk_window_set_child (window, picture);
  add_pixel_picture (GTK_PICTURE (picture));

  gtk_window_present (window);
}

int
main (int   argc,
      char *argv[])
{
  g_autoptr(GtkApplication) app = gtk_application_new (NULL, 0);

  g_signal_connect (app, "activate", G_CALLBACK (app_activated_cb), NULL);

  return g_application_run (G_APPLICATION (app), argc, argv);
}

使用适合您的数据的 GdkMemoryFormat,或将其转换为受支持的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-15
    • 2015-12-02
    相关资源
    最近更新 更多