将灰度转换为 RGB
Convert Grayscale to 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 个像素。我希望有人知道我的意思,并且可以 link 告诉我我忽略的信息。
编辑:
#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;
}
这是我用来显示图像的程序。我用相机拍照的密码不能分享。
您的代码有 1 个主要问题:
您使用错误的 rowstride
值创建了 pixbuf
。它以字节为单位,而不是以像素为单位。对于 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;
}
我的问题是:我的缓冲区中有一张图片 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 个像素。我希望有人知道我的意思,并且可以 link 告诉我我忽略的信息。
编辑:
#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;
}
这是我用来显示图像的程序。我用相机拍照的密码不能分享。
您的代码有 1 个主要问题:
您使用错误的 rowstride
值创建了 pixbuf
。它以字节为单位,而不是以像素为单位。对于 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;
}