fltk动态分配数据显示图像

      fltk中在控件上显示图像可以使用生成静态数组的方式,用的时候直接加载显示即可,但是这种方式对于只是开始时显示以后就不用的图像,静态数组不能随后释放,特别是在图像比较大时会占用大量的内存。

     可以使用fluid将图像转换的静态数组转换为图像数据,在使用的时候读入,用完之后释放,这样就可以节省一部分资源。

     下面是一个将fluid生成的图像数据静态数组转换为数据文件然后在使用时加载的例子。

      首先是将静态数组文件读取出来:

[cpp] view plain copy print ?
  1. size_t parse_imgdata_file(const char *file_name, unsigned char *pdata)  
  2. {  
  3.     if(pdata == NULL)  
  4.         return 0;  
  5.     FILE *fp = fopen(file_name, "rt");  
  6.     if(fp == NULL)  
  7.         return 0;  
  8.   
  9.     if(fseek(fp, 0, SEEK_END) != 0)  
  10.     {  
  11.         fclose(fp);  
  12.         return 0;  
  13.     }  
  14.     long file_len = ftell(fp);  
  15.     if(file_len == -1)  
  16.     {  
  17.         fclose(fp);  
  18.         return 0;  
  19.     }  
  20.     fseek(fp, 0, SEEK_SET);  
  21.   
  22.     char *temp = new char[file_len+1];  
  23.     if(temp == NULL)  
  24.     {  
  25.         fclose(fp);  
  26.         return 0;  
  27.     }  
  28.     memset(temp, 0, file_len+1);  
  29.   
  30.     long rd_len = fread(temp, 1, file_len, fp);  
  31.     if(rd_len==0 && ferror(fp)!=0)  
  32.     {  
  33.         fclose(fp);  
  34.         delete []temp;  
  35.         return 0;  
  36.     }  
  37.   
  38.     size_t cnt = 0;  
  39.     char *beg_pos = strchr(temp, '{');  
  40.     char *end_pos = strchr(temp, '}');  
  41.     if(beg_pos==NULL || end_pos==NULL)  
  42.     {  
  43.         fclose(fp);  
  44.         delete []temp;  
  45.         return 0;  
  46.     }  
  47.   
  48.     char num_str[5] = {0};  
  49.     for (char *find_pos = ++beg_pos; find_pos<end_pos;)  
  50.     {  
  51.         if(isdigit(*find_pos))  
  52.         {         
  53.             int i=0;  
  54.             while(isdigit(*find_pos))  
  55.                 num_str[i++] = *find_pos++;  
  56.             pdata[cnt++] = (unsigned char)atoi(num_str);  
  57.             memset(num_str, 0, 5);  
  58.         }  
  59.         else  
  60.             ++find_pos;  
  61.     }  
  62.   
  63.     fclose(fp);  
  64.     delete []temp;  
  65.     return cnt;  
  66. }  


需要注意的是数据区需要在外面分配,因为图像的大小肯定是已知的,所以分配内存不难;

下面是将读取到的数据保存到纯数据文件中(当然可以直接使用上面的程序读取数据然后用,但是有个parse的过程比较慢,所以还是直接保存为数据文件读取的时候比较快一些)。

[cpp] view plain copy print ?
  1. size_t store_imgdata(const char *file_name, unsigned char *pdata, size_t data_len)  
  2. {  
  3.     if(pdata == NULL)  
  4.         return 0;  
  5.     FILE *fp = fopen(file_name, "wb");  
  6.     if(fp == NULL)  
  7.         return 0;  
  8.       
  9.     size_t store_len = fwrite(pdata, data_len, 1, fp);  
  10.   
  11.     fclose(fp);  
  12.     return (store_len==1 ? data_len : 0);  
  13. }  


最后是使用的时候的读取数据文件的函数:

[cpp] view plain copy print ?
  1. size_t load_imgdata(const char *file_name, unsigned char *pdata, size_t data_len)  
  2. {  
  3.     if(pdata == NULL)  
  4.         return 0;  
  5.     FILE *fp = fopen(file_name, "rb");  
  6.     if(fp == NULL)  
  7.         return 0;  
  8.   
  9.     size_t load_len = fread(pdata, data_len, 1, fp);  
  10.   
  11.     fclose(fp);  
  12.     return (load_len==1 ? data_len : 0);  
  13. }  

其实函数都比较简单,相比较于使用静态数组的方式加载图像,这种方式会慢一些,但是静态加载在图像太大时,静态编译的栈可能会溢出导致无法编译,需要修改栈大小,而且编译会很慢;这种动态的方式就快多了,当然前期的转换工作需要人工来做。下面是一个测试的例子:

[cpp] view plain copy print ?
  1. int main(int argc, char *argv[])   
  2. {  
  3.     size_t sz = 175*126*3;  
  4.     unsigned char *pdata = new unsigned char[sz];  
  5.     size_t len = load_imgdata("test.dat", pdata, sz);  
  6.   
  7.     printf("len =%u\n", len);  
  8.   
  9.     Fl::scheme("GTK+");  
  10.     Fl_Window *win = new Fl_Window(800,400,"Tabs Example");  
  11.     {         
  12.         Fl_Button *btn = new Fl_Button(120, 140, 200, 200, "button");  
  13.         Fl_RGB_Image *img = new Fl_RGB_Image(pdata, 175, 126);  
  14.         btn->image(img);  
  15.     }  
  16.     win->end();  
  17.     win->show(argc, argv);  
  18.     return(Fl::run());  
  19. }  


显示结果如下:

fltk动态分配数据显示图像_第1张图片

图像数据是自己随便写入的,所以不是什么规则的图像,但是显示是没有问题的。

 

你可能感兴趣的:(fltk动态分配数据显示图像)