fltk中在控件上显示图像可以使用生成静态数组的方式,用的时候直接加载显示即可,但是这种方式对于只是开始时显示以后就不用的图像,静态数组不能随后释放,特别是在图像比较大时会占用大量的内存。
可以使用fluid将图像转换的静态数组转换为图像数据,在使用的时候读入,用完之后释放,这样就可以节省一部分资源。
下面是一个将fluid生成的图像数据静态数组转换为数据文件然后在使用时加载的例子。
首先是将静态数组文件读取出来:
- size_tparse_imgdata_file(constchar*file_name,unsignedchar*pdata)
- {
-
if(pdata==NULL)
-
return0;
-
FILE*fp=fopen(file_name,"rt");
-
if(fp==NULL)
-
return0;
-
if(fseek(fp,0,SEEK_END)!=0)
- {
- fclose(fp);
-
return0;
- }
-
longfile_len=ftell(fp);
-
if(file_len==-1)
- {
- fclose(fp);
-
return0;
- }
- fseek(fp,0,SEEK_SET);
-
char*temp=newchar[file_len+1];
-
if(temp==NULL)
- {
- fclose(fp);
-
return0;
- }
- memset(temp,0,file_len+1);
-
longrd_len=fread(temp,1,file_len,fp);
-
if(rd_len==0&&ferror(fp)!=0)
- {
- fclose(fp);
-
delete[]temp;
-
return0;
- }
-
size_tcnt=0;
-
char*beg_pos=strchr(temp,'{');
-
char*end_pos=strchr(temp,'}');
-
if(beg_pos==NULL||end_pos==NULL)
- {
- fclose(fp);
-
delete[]temp;
-
return0;
- }
-
charnum_str[5]={0};
-
for(char*find_pos=++beg_pos;find_pos<end_pos;)
- {
-
if(isdigit(*find_pos))
- {
-
inti=0;
-
while(isdigit(*find_pos))
- num_str[i++]=*find_pos++;
-
pdata[cnt++]=(unsignedchar)atoi(num_str);
- memset(num_str,0,5);
- }
-
else
- ++find_pos;
- }
- fclose(fp);
-
delete[]temp;
-
returncnt;
- }
size_t parse_imgdata_file(const char *file_name, unsigned char *pdata)
{
if(pdata == NULL)
return 0;
FILE *fp = fopen(file_name, "rt");
if(fp == NULL)
return 0;
if(fseek(fp, 0, SEEK_END) != 0)
{
fclose(fp);
return 0;
}
long file_len = ftell(fp);
if(file_len == -1)
{
fclose(fp);
return 0;
}
fseek(fp, 0, SEEK_SET);
char *temp = new char[file_len+1];
if(temp == NULL)
{
fclose(fp);
return 0;
}
memset(temp, 0, file_len+1);
long rd_len = fread(temp, 1, file_len, fp);
if(rd_len==0 && ferror(fp)!=0)
{
fclose(fp);
delete []temp;
return 0;
}
size_t cnt = 0;
char *beg_pos = strchr(temp, '{');
char *end_pos = strchr(temp, '}');
if(beg_pos==NULL || end_pos==NULL)
{
fclose(fp);
delete []temp;
return 0;
}
char num_str[5] = {0};
for (char *find_pos = ++beg_pos; find_pos<end_pos;)
{
if(isdigit(*find_pos))
{
int i=0;
while(isdigit(*find_pos))
num_str[i++] = *find_pos++;
pdata[cnt++] = (unsigned char)atoi(num_str);
memset(num_str, 0, 5);
}
else
++find_pos;
}
fclose(fp);
delete []temp;
return cnt;
}
需要注意的是数据区需要在外面分配,因为图像的大小肯定是已知的,所以分配内存不难;
下面是将读取到的数据保存到纯数据文件中(当然可以直接使用上面的程序读取数据然后用,但是有个parse的过程比较慢,所以还是直接保存为数据文件读取的时候比较快一些)。
- size_tstore_imgdata(constchar*file_name,unsignedchar*pdata,size_tdata_len)
- {
-
if(pdata==NULL)
-
return0;
-
FILE*fp=fopen(file_name,"wb");
-
if(fp==NULL)
-
return0;
-
size_tstore_len=fwrite(pdata,data_len,1,fp);
- fclose(fp);
-
return(store_len==1?data_len:0);
- }
size_t store_imgdata(const char *file_name, unsigned char *pdata, size_t data_len)
{
if(pdata == NULL)
return 0;
FILE *fp = fopen(file_name, "wb");
if(fp == NULL)
return 0;
size_t store_len = fwrite(pdata, data_len, 1, fp);
fclose(fp);
return (store_len==1 ? data_len : 0);
}
最后是使用的时候的读取数据文件的函数:
- size_tload_imgdata(constchar*file_name,unsignedchar*pdata,size_tdata_len)
- {
-
if(pdata==NULL)
-
return0;
-
FILE*fp=fopen(file_name,"rb");
-
if(fp==NULL)
-
return0;
-
size_tload_len=fread(pdata,data_len,1,fp);
- fclose(fp);
-
return(load_len==1?data_len:0);
- }
size_t load_imgdata(const char *file_name, unsigned char *pdata, size_t data_len)
{
if(pdata == NULL)
return 0;
FILE *fp = fopen(file_name, "rb");
if(fp == NULL)
return 0;
size_t load_len = fread(pdata, data_len, 1, fp);
fclose(fp);
return (load_len==1 ? data_len : 0);
}
其实函数都比较简单,相比较于使用静态数组的方式加载图像,这种方式会慢一些,但是静态加载在图像太大时,静态编译的栈可能会溢出导致无法编译,需要修改栈大小,而且编译会很慢;这种动态的方式就快多了,当然前期的转换工作需要人工来做。下面是一个测试的例子:
- intmain(intargc,char*argv[])
- {
-
size_tsz=175*126*3;
-
unsignedchar*pdata=newunsignedchar[sz];
-
size_tlen=load_imgdata("test.dat",pdata,sz);
-
printf("len=%u\n",len);
-
Fl::scheme("GTK+");
-
Fl_Window*win=newFl_Window(800,400,"TabsExample");
- {
-
Fl_Button*btn=newFl_Button(120,140,200,200,"button");
-
Fl_RGB_Image*img=newFl_RGB_Image(pdata,175,126);
- btn->image(img);
- }
- win->end();
- win->show(argc,argv);
-
return(Fl::run());
- }
int main(int argc, char *argv[])
{
size_t sz = 175*126*3;
unsigned char *pdata = new unsigned char[sz];
size_t len = load_imgdata("test.dat", pdata, sz);
printf("len =%u\n", len);
Fl::scheme("GTK+");
Fl_Window *win = new Fl_Window(800,400,"Tabs Example");
{
Fl_Button *btn = new Fl_Button(120, 140, 200, 200, "button");
Fl_RGB_Image *img = new Fl_RGB_Image(pdata, 175, 126);
btn->image(img);
}
win->end();
win->show(argc, argv);
return(Fl::run());
}
显示结果如下:
图像数据是自己随便写入的,所以不是什么规则的图像,但是显示是没有问题的。
分享到:
相关推荐
利用VC2010 CMAKE编译的FLTK库文件
简单实现了Button的按下和弹起状态的改变。 需要自己配置一下图像源文件夹。并将路径更改即可
里面包括fltk中文文档,四部fltk pdf资料,及html资料,还有fltk的产品总体架构图,收集了很久
基于FLTK的小钟,学习FLTK用
关于仪表显示库FLTK的使用指南,英文版
这是很好的FLTK的指导书啊,大家如果需要的话就来下载吧,嘻嘻
详细列出了fltk中种类的关系及它们的在总体架构中的分部,对fltk编程的人员对很有用哦
FLTK-Tutorial.
课程作业代码 FLTK五子棋 实现双人对战 人机对战 图形化界面
附件是FLTK 1.3.2的用书手册(FLTK Programming Manual)。内容均是摘自FLTK官网,但是官网是网页版,阅读标记不太方便,我将其制作成pdf浏览,在这给大家共享一下~~
这是一个用FLTK+sqlite编写的一个编码分配器,编程语言为C++。关于FLTK是一个C++ GUI库,更多信息请访问(http://www.fltk.org/index.php)。关于sqlite的更多信息请访问(http://www.sqlite.org/index.html)。 为...
FLTK跨平台界面库在.NET下应用(国外swf,~5M)
c++ 轻巧的 gui库 fltk 的源码
收集了一些fltk入门的中文教程,还不错,里面还有一些例子,对初学者很有帮助
基于C++的轻量级UI设计库,由于它同时支持在Windows和Linux,所以对跨平台使用非常有用。
fltk-draw-demo
VC6中使用FLTK FLTK,如同其名字所表达的:The Fast Light Tool Kit,一个轻量级的GUI开发库。但这轻量级并不代表功能的羸弱,相反,FLTK在具有基本的GUI功能之外,还拥有一些特殊的功能,比如跨平台、内置 OpenGL...
FLTK 最新的r6786版本,已编译,并测试成功! 源代码如果使用UTF-8,使用GCC编译器,中文支持很完美!
不错的FLTK资料,详细描述了FLTK的使用
FLTK,如同其名字所表达的:The Fast Light Tool Kit,一个轻量级的GUI开发库。但这轻量级并不代表功能的羸弱,相反,FLTK在具有基本的GUI功能之外,还拥有一些特殊的功能,比如跨平台、内置 OpenGL功能、速度更快、...