在GTK 4.0中用C语言绘制像素数组的最简单方法

i2loujxw  于 2022-12-11  发布在  其他
关注(0)|答案(1)|浏览(217)

我试图找到一个在GTK 4.0中显示现有内存缓冲区中的图像的示例,其中图像以大小为 * 宽度x高度x 3* 的浮点数数组的形式存储。我知道我需要使用GtkImage,但我不知道如何将这样的数组传递给它。
只是为了说明上下文,我想实现一个原型来渲染一些图像,它们都是在内存中渲染的,因此,我有一个这样的浮点数数组,每个像素有三个浮点数。不幸的是,我找不到最新的GTK 4.0的任何示例。有很多从磁盘加载图像的示例,但对于我的情况来说,这似乎像是跳不必要的铁环。我曾经将这些作为OpenGL纹理加载,并在一个四轴上显示,但这也似乎像是用大锤钉钉子。
提前感谢您的任何帮助!

hkmswyz6

hkmswyz61#

您可以对内存中的图像使用GdkMemoryTexture,使用GtkPicture并使用gtk_picture_set_paintable()设置纹理以对其进行绘制。以下是创建不透明的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;

  /* 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,或将其转换为受支持的GdkMemoryFormat

相关问题