基于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;
}
其他注意
使用stb image.h的时候提示需要链接math库,也就是CMakeLists.txt中target_link_libraries
时加上m
。
参考
Display a sequence of images using gtk in Linux
基于gtk的imshow:用stb_image读取图像并用gtk显示的更多相关文章
- 【QT】对话框打开图像并用QPixmap显示
绘图设备是指继承QPaintDevice的子类,可以使用QPainter直接在其上面绘制图形,Qt一共提供了四个这样继承QPaintDevice的绘图设备类. 分别是QPixmap.QBitmap.Q ...
- 基于gtk的imshow:用gtk读取并显示图像
gtk实现imshow,最naive的做法是用gtk的组件去读取图像,然后show出来:后续再考虑用GTK显示用别的方式例如stb image读取的图像.先前基于GDI实现imshow时也是这一思路, ...
- 最简单的基于FFmpeg的AVDevice例子(读取摄像头)
=====================================================最简单的基于FFmpeg的AVDevice例子文章列表: 最简单的基于FFmpeg的AVDev ...
- 基于FPGA的线阵CCD实时图像采集系统
基于FPGA的线阵CCD实时图像采集系统 2015年微型机与应用第13期 作者:章金敏,张 菁,陈梦苇2016/2/8 20:52:00 关键词: 实时采集 电荷耦合器件 现场可编程逻辑器件 信号处理 ...
- [转载] 最简单的基于FFmpeg的AVDevice例子(读取摄像头)
=====================================================最简单的基于FFmpeg的AVDevice例子文章列表: 最简单的基于FFmpeg的AVDev ...
- 最简单的基于FFmpeg的AVDevice例子(读取摄像头)【转】
转自:http://blog.csdn.net/leixiaohua1020/article/details/39702113 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[- ...
- OpenCV2:第三章 读取图像
一.简介 将图像文件读入内存,可以用cv::imread()函数 二.读取图像 Mat imread(const string& filename,int flags=1); Mat: 如果读 ...
- OpenCV读取图像问题:OpenCV(3.4.3) D:\Build\OpenCV\opencv-size.width0 && size.height0 in function 'cvimshow'
版权声明:本文为博主原创文章,转载 请注明出处:https://blog.csdn.net/sc2079/article/details/83280067 - 问题与解决 最近正在学OpenCV,发现 ...
- opencv学习之读取图像-imread函数
序 想要完整全面地学习opencv,仅凭阅读samples的示例源码是不够的.毕竟opencv是一个拥有非常多函数的程序库,所以在每学习一个函数时,芒果觉得有必要记录下来,分享给有需要的同学.于是,就 ...
随机推荐
- Axure8.1.0.3388 授权码
Licensee:www.jb51.net Key:5eKQiVe0zlGqMijERRp6ancI2jGAxhuejGWvk2oWClywQSB/Mrq72wYhj7D9gAKC
- php nl2br 将\n变成<br />
<?php $str="h t m l"; //定义一个多处换行的字串 echo "未处理前的输出形式:<br />{$str}"; #nl2 ...
- Spring Boot入门学习,解决复杂的spring配置文件及jar包
转载:https://www.cnblogs.com/wmyskxz/p/9010832.html 总结 为何出了这样的框架? Spring Boot 是所有基于 Spring 开发的项目的起点.Sp ...
- 词向量 词嵌入 word embedding
词嵌入 word embedding embedding 嵌入 embedding: 嵌入, 在数学上表示一个映射f:x->y, 是将x所在的空间映射到y所在空间上去,并且在x空间中每一个x有y ...
- os.environ详解
我们想要用Python获得一些有关系统的各种信息的时候就不得不想到os的environ,那这里面都具体包含了那些内容呢? 简介 对于官方的解释,environ是一个字符串所对应环境的映像对象.这是什么 ...
- LeetCode_448. Find All Numbers Disappeared in an Array
448. Find All Numbers Disappeared in an Array Easy Given an array of integers where 1 ≤ a[i] ≤ n (n ...
- dotnet core 项目脚手架这种小事嘛...
dotnet core脚手架批处理.bat @echo 请修改批处理文件名后,如:Example.Core ,注释掉goto end,再执行脚本 pause goto end ::goto end s ...
- Python3使用random生成随机数
本文介绍使用Python3中的random库生成随机数.随机小数.随机序列.随机字符串以及扑克洗牌等方法. 一.生成随机浮点数或小数 1.#生成0-1之间的浮点数 import random rnd ...
- spark 性能优化简要总结
1.从同一个数据源尽量只创建一个rdd,后续业务逻辑复用该rdd2.如果要对某个rdd进行多次的transformation或action操作,应当持久化该rdd3.从数据源读取到rdd后,要尽早的进 ...
- webx入门