gtk读取bmp二维数组并显示
时间: 2023-08-04 11:08:16 浏览: 162
下面是一个简单的使用GTK+读取BMP文件并将其显示在窗口中的示例代码:
```c
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int width;
int height;
unsigned char *data;
} BMPImage;
BMPImage *loadBMP(const char *filename) {
FILE *file;
BMPImage *image;
file = fopen(filename, "rb");
if (!file) {
fprintf(stderr, "Error: failed to open file '%s'\n", filename);
return NULL;
}
image = (BMPImage*) malloc(sizeof(BMPImage));
if (!image) {
fprintf(stderr, "Error: failed to allocate memory\n");
fclose(file);
return NULL;
}
// Read BMP header
fseek(file, 18, SEEK_SET);
fread(&image->width, sizeof(int), 1, file);
fread(&image->height, sizeof(int), 1, file);
// Allocate memory for image data
image->data = (unsigned char*) malloc(image->width * image->height * 3);
if (!image->data) {
fprintf(stderr, "Error: failed to allocate memory\n");
free(image);
fclose(file);
return NULL;
}
// Read image data
fseek(file, 54, SEEK_SET);
fread(image->data, 3, image->width * image->height, file);
fclose(file);
return image;
}
void freeBMP(BMPImage *image) {
if (image) {
if (image->data) {
free(image->data);
}
free(image);
}
}
void drawBMP(GtkWidget *widget, cairo_t *cr, BMPImage *image) {
int x, y;
unsigned char *p;
for (y = 0; y < image->height; y++) {
for (x = 0; x < image->width; x++) {
p = image->data + (y * image->width + x) * 3;
cairo_set_source_rgb(cr, p[2] / 255.0, p[1] / 255.0, p[0] / 255.0);
cairo_rectangle(cr, x, y, 1, 1);
cairo_fill(cr);
}
}
}
int main(int argc, char **argv) {
GtkWidget *window;
GtkWidget *drawing_area;
BMPImage *image;
if (argc < 2) {
fprintf(stderr, "Usage: %s <filename.bmp>\n", argv[0]);
return 1;
}
// Load BMP file
image = loadBMP(argv[1]);
if (!image) {
return 1;
}
// Initialize GTK+
gtk_init(&argc, &argv);
// Create window
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "BMP Viewer");
gtk_window_set_default_size(GTK_WINDOW(window), image->width, image->height);
// Create drawing area
drawing_area = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), drawing_area);
// Connect signals
g_signal_connect(G_OBJECT(drawing_area), "draw", G_CALLBACK(drawBMP), image);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
// Show window
gtk_widget_show_all(window);
// Start main loop
gtk_main();
// Free resources
freeBMP(image);
return 0;
}
```
代码中的`loadBMP`函数负责读取BMP文件并返回一个包含图像数据的结构体。`drawBMP`函数则负责将图像数据绘制在GTK+的绘图区域中。注意,这里使用了Cairo库来进行绘图。
在`main`函数中,我们首先调用`loadBMP`函数来读取BMP文件,然后创建一个GTK+窗口和一个绘图区域。接着,我们通过`g_signal_connect`函数将`drawBMP`函数与绘图区域的`draw`信号连接起来,这样每当需要绘制窗口时,GTK+就会自动调用`drawBMP`函数。最后,我们通过调用`gtk_main`函数来启动GTK+的主循环,等待用户交互事件发生。
如果你想将该示例代码运行起来,需要在编译时链接GTK+和Cairo库。以gcc为例,你可以使用下面的命令进行编译:
```
gcc -o bmpviewer bmpviewer.c `pkg-config --cflags --libs gtk+-3.0 cairo`
```
该命令会自动将GTK+和Cairo库链接到你的程序中。
阅读全文