基于gtk的imshow:用stb_image读取图像并用gtk显示

在前面一篇,已经能够基于gtk读取图像并显示。更前面的一篇:基于GDI的imshow:使用stb_image读取图像并修正绘制,通过stb_image读取图像并通过GDI显示图像,实现了一个imshow。本篇则在这两基础上,利用stb_image读取图像,并利用gtk显示,初步实现一个基于gtk的imshow。

首先是找到一份代码,从指定的buffer创建gtk的image并显示(参考1)。然后用stb image读取,先前我进行了封装,得到fc image是和opencv兼容的bgr格式。然而发现gtk需要的是rgb的顺序,因此又做了一道转化步骤:BGR to RGB,然后把对应的buffer传给gtk去生成它的image。

代码实现

完整的代码需要 基于GDI的imshow:使用stb_image读取图像并修正绘制 这一篇blog中的代码,以及本文新增的代码gtk_show_image_v3.c:

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

#include "fc_image.h"

void fc_bgr_to_rgb(FcImage* im) {
    if (im==NULL) return;
    if (im->c<=0 || im->h<=0 || im->w==0) return;
    assert(im->c==3);

    int num_pixel = im->c * im->h * im->w;
    unsigned char t;
    for(int i=0; i<num_pixel; i+=3) {
        t = im->data[i];
        im->data[i] = im->data[i+2];
        im->data[i+2] = t;
    }
}

int main (int argc, char *argv[])
{
    const char* im_pth = "/home/zz/work/libfc/imgs/fruits.jpg";
    FcImage im = fc_load_image(im_pth);
    fc_bgr_to_rgb(&im);

    GtkWidget *window;
    GtkWidget* image;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data (im.data, GDK_COLORSPACE_RGB,
        FALSE, 8, im.w, im.h, im.w*3, 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 ();

    return 0;
}

简单封装

考虑到把原有的bgr顺序的图像buffer修改为rgb,就地修改肯定是有问题的,影响到后续算法的使用。因此应当拷贝产生一个新的图像数据。并且还需要把im和title作为参数,封装为API,以后调用方便。修改后的代码如下:

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

#include "fc_image.h"

void fc_copy_bgr_to_rgb(const FcImage* src, FcImage* dst) {
    if (src==NULL) return;
    if (dst==NULL) return;
    assert(src!=dst);
    assert(src->data!=NULL);
    assert(dst->data!=NULL);
    assert(src->data!=dst->data);
    assert(src->c>=0 && src->h>=0 && src->c==3);
    assert(src->c>=0 && src->h>=0 && src->c==3);
    assert(src->c==dst->c && src->h==dst->h && src->w==dst->w);

    int num_pixel = src->c * src->h * src->w;
    for(int i=0; i<num_pixel; i+=3) {
        dst->data[i] = src->data[i+2];
        dst->data[i+1] = src->data[i+1];
        dst->data[i+2] = src->data[i];
    }
}

FcImage fc_make_image(int w, int h, int c)
{
    FcImage out;
    out.w = w;
    out.h = h;
    out.c = c;
    out.data = (unsigned char*)calloc(h*w*c, sizeof(float));
    return out;
}

void gtk_show_image_v3(const FcImage* im, const char* title)
{
    FcImage im_rgb = fc_make_image(im->w, im->h, im->c); //?? check this dimensions
    fc_copy_bgr_to_rgb(im, &im_rgb);

    GtkWidget *window;
    GtkWidget* image;

    gtk_init (NULL, NULL);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data (im_rgb.data, GDK_COLORSPACE_RGB,
        FALSE, 8, im_rgb.w, im_rgb.h, im_rgb.w*3, NULL, NULL);

    gtk_window_set_title (GTK_WINDOW (window), title);

    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 ();
}

int main (int argc, char *argv[])
{
    const char* im_pth = "/home/zz/work/libfc/imgs/fruits.jpg";
    FcImage im = fc_load_image(im_pth);
    const char* title = "fruits";
    gtk_show_image_v3(&im, title);

    return 0;
}

参考

Display a sequence of images using gtk in Linux

原文地址:https://www.cnblogs.com/zjutzz/p/10960235.html

时间: 2024-11-05 22:02:38

基于gtk的imshow:用stb_image读取图像并用gtk显示的相关文章

【QT】对话框打开图像并用QPixmap显示

绘图设备是指继承QPaintDevice的子类,可以使用QPainter直接在其上面绘制图形,Qt一共提供了四个这样继承QPaintDevice的绘图设备类. 分别是QPixmap.QBitmap.QImage和 QPicture. //打开文件对话框 QString lastPath="D:/Englishpath/QTprojects/DATA/videoData"; fileName = QFileDialog::getOpenFileName(this, tr("打开

最简单的基于FFmpeg的AVDevice例子(读取摄像头)【转】

转自:http://blog.csdn.net/leixiaohua1020/article/details/39702113 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] libavdevice使用 注意事项 代码 结果 下载 =====================================================最简单的基于FFmpeg的AVDevice例子文章列表: 最简单的基于FFmpeg的AVDevice例子(读取摄像头) 最简单的基于FFm

最简单的基于FFmpeg的AVDevice例子(读取摄像头)

FFmpeg中有一个和多媒体设备交互的类库:Libavdevice.使用这个库可以读取电脑(或者其他设备上)的多媒体设备的数据,或者输出数据到指定的多媒体设备上.Libavdevice支持以下设备作为输入端: alsaavfoundationbktrdshowdv1394fbdevgdigrabiec61883jacklavfilibcdiolibdc1394openalosspulseqtkitsndiovideo4linux2, v4l2vfwcapx11grabdecklink Libav

openvc中读取图像访问图像中像元的的方法

一.读取图像 1.利用Mat数据结构读取和显示图片 #include"cv.h" #include "highgui.h" #include<iostream> using namespace std; using namespace cv; int _tmain(int argc, _TCHAR* argv[]) { Mat img=imread("./ImageData/sf1.png");//图片的相对路径 namedWindo

python3随笔-opencv读取图像数据

如何安装opencv-python $pip3 install opencv-python 如何读取图像数据 import numpy as np import cv2 as cv img = cv.imread('1.png') print(img) print(img.dtype) [[[200 228 197][200 228 197][200 228 197]......[200 228 197][200 228 197][200 228 197]]] dtype('uint8') 使用

Matlab在读取图像时怎么实现手动选择图像

平时看的一些关于图像处理的文献通常要在matlab里面写一下,以便加深对这个算法的理解,当然写好以后需要图像来测试,以前我常常在 path='图像所在的路径'; img=imread(path+图像的名字); 在imread函数中进行不断修改图像的名字,以便测试不同的图像对于该算法的效果如何. 想必大家也是常常这样做实验吧,今天突然想,这样一直改名字多麻烦多浪费时间,我觉得像Matlab这么强大的软件肯定提供这样的函数给用户,因为每个软件都要考虑用户体验的哈! 在网上搜了很久没找到非常好的答案,

GDAL库——读取图像并提取基本信息

GDAL库是一个跨平台的栅格地理数据格式库,包括读取.写入.转换.处理各种栅格数据格式(有些特定的格式对一些操作如写入等不支持).它使用了一个单一的抽象数据模型就支持了大多数的栅格数据.这里有GDAL库支持的格式:http://www.gdal.org/formats_list.html 注:本文在Qt开发环境下使用GDAL库. 在Qt中使用GDAL库时,除了要加gdal_priv.h头文件外,还需要在xxx.pro文件内加上LIBS += -lgdal ,文件用可编辑的文档打开. 使用GDAL

用opencv读取图像鼠标点的像素,更正一个Bug

作者:skyseraph 出处:http://www.cnblogs.com/skyseraph/ 以下代码在网上流传很广. 不过,调试运行之后发现,功能是正确的,但是内存很快就耗尽,导致死机.经过查找,加上: cvReleaseImage(&img1);    //释放源图像占用的内存 这一行是我(szliug)加的,否则内存很快就会耗尽,会死机的. 之后运行正常. /*===============================================// 功能:OpenCV Ut

Exif.js 读取图像的元数据

Exif.js 提供了 JavaScript 读取图像的原始数据的功能扩展,例如:拍照方向.相机设备型号.拍摄时间.ISO 感光度.GPS 地理位置等数据. 注意事项: EXIF 数据主要来自拍摄的照片,多用于移动端开发,PC 端也会用到,此插件兼容主流浏览器,IE10 以下不支持. github地址 在线实例 实例预览 简单示例 实例预览 获取 base64 编码文件数据 实例预览 异步获取图像数据 使用方法 载入 JavaScript 文件 <script src="exif.js&q