首页 > 解决方案 > 将灰度转换为 RGB

问题描述

我的问题是:我的缓冲区中有一张图片buffer = (unsigned short *) malloc(imageSize*2);

这张图片是每像素 8 位,每像素 1 字节,所以它是灰度图。

但要显示它,我需要一张 RGB 图片。因为只支持RGB图片。 例子

所以我需要从以下位置更改图片:

index     |  1    |  2    |...
grayvalue |  128  |  135  |...

index     |  1            |  2            |...
grayvalue |  128,128,128  |  135,135,135  |...

为| r,g,b |。

我的想法是从缓冲区创建一个数组array[grayvalue] = buffer[count],以某种方式将 2 个灰度值添加到同一个像素并将数组更改回缓冲区。但我找不到如何从缓冲区获取数组以及如何将灰度值添加到 1 个像素。我希望有人知道我的意思,并可以将我链接到我忽略的信息。

编辑:

#include <stdlib.h>
#include <gtk/gtk.h>

int main (int argc, char *argv[])
{
    long int imageSize = 0;
    unsigned short *buffer = NULL;

    const int Width = 1936, Height = 1460;

    /*code to take raw image data from camera*/


   // Put raw image data from the camera in the buffer.     
      buffer = (unsigned short *) malloc(imageSize*2);


    // GTK

    GtkWidget *window;
    GtkWidget* image;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data ((unsigned short *) buffer, GDK_COLORSPACE_RGB,FALSE, 8,
               Width, Height, Width*1, NULL, NULL);

    gtk_window_set_title (GTK_WINDOW (window), "Image Viewer");
    g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
    image = gtk_image_new_from_pixbuf (pixbuf);
    gtk_container_add(GTK_CONTAINER (window), image);
    gtk_widget_show_all (window);
    gtk_main ();
    free (buffer);
    return 0;
}

这是我用来显示我的图像的程序。我用来用相机拍照的代码无法共享。

标签: arrayscbuffer

解决方案


您的代码有 1 个主要问题:您创建了pixbuf错误的rowstride值。它以字节为单位,而不是以像素为单位。对于 RGB 像素,您需要 3 个字节。

修复此问题后,您需要将灰度像素转换为 RGBB 像素。这不是“组合像素”,而是简单地重复相同的值。

这是一些将 8 位灰度转换为 24 位 RGB 像素的示例代码:

// build:
// gcc -o test `pkg-config --cflags gtk+-3.0` test.c `pkg-config --libs gtk+-3.0`

#include <stdlib.h>
#include <stdint.h>
#include <gtk/gtk.h>

typedef struct {
  uint8_t r;
  uint8_t g;
  uint8_t b;
} rgb;

int main (int argc, char *argv[])
{
    size_t Width  = 1936;
    size_t Height = 1280;
    size_t Stride_8 = Width;   // Might need rounding up
    size_t Stride_rgb = Width; // Might need rounding up

    //Due to lack of camera data, lets use some dummy data...
    uint8_t *buffer_8 = malloc(Stride_8*Height);
    for (size_t x = 0; x < Width; x++)
      for (size_t y = 0; y < Height; y++)
        buffer_8[Stride_8*y + x] = (x+y) & 0xFF;

    /*code to take raw image data from camera*/

    // Put greyscale image data from the camera into the RGB buffer.     
    rgb *buffer_rgb = malloc(Stride_rgb * Height * sizeof(rgb));
    for (size_t x = 0; x < Width; x++)
      for (size_t y = 0; y < Height; y++)
      {
        // Convert 1 byte greyscale in 3 byte RGB:
        uint8_t grey = buffer_8[Stride_8*y + x];
        buffer_rgb[Stride_rgb*y + x].r = grey;
        buffer_rgb[Stride_rgb*y + x].g = grey;
        buffer_rgb[Stride_rgb*y + x].b = grey;
        }

    // GTK
    gtk_init(&argc, &argv);
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW (window), "test");
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GdkPixbuf *pixbuf_rgb = gdk_pixbuf_new_from_data((guchar*)buffer_rgb, GDK_COLORSPACE_RGB,FALSE, 8,
               Width, Height, Stride_rgb*3, NULL, NULL);
    GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf_rgb);

    gtk_container_add(GTK_CONTAINER(window), image);
    gtk_widget_show_all(window);
    gtk_main();
    free(buffer_rgb);
    free(buffer_8);
    return 0;
}

推荐阅读