|
将图片转换为数据(imgtodata)
第一步,先获取图片的数据信息:- pixbuf = gdk_pixbuf_new_from_file(open_filename, NULL);
- data = gdk_pixbuf_get_pixels(pixbuf);//获得图片像素的数据,数据类型为guchar
- width = gdk_pixbuf_get_width(pixbuf);
- height = gdk_pixbuf_get_height(pixbuf);
- stride = gdk_pixbuf_get_rowstride(pixbuf);//一行像素所占的字节数。
- n_channels = gdk_pixbuf_get_n_channels (pixbuf);//如果图片为RGB格式即此值为3,如果是RGBA格式则此值为4
复制代码 由于本例中图片再现是用cairo_image_surface_create_for_data() 来实现的,数据的排列方式跟PIXBUF不一样,所以要做一下处理。
第二步,数据重新排列:- bytesperpixel = n_channels;
- cairostride = stride;
- if(n_channels == 3)
- {
- bytesperpixel += 1;
- cairostride = width * 4;
- }
- if(cairodata != NULL)
- g_free(cairodata);
- cairodata = g_malloc0(cairostride*height);
- for(y = 0; y < height; y++)
- {
- for(x = 0; x < width; x++)
- {
- pdata = data + y * stride + x * n_channels;
- pcdata = cairodata + y * cairostride + x * bytesperpixel;
- pcdata[0] = pdata[2];
- pcdata[1] = pdata[1];
- pcdata[2] = pdata[0];
- if(n_channels == bytesperpixel)
- pcdata[3] = pdata[3];
- }
- }
复制代码 至此cairodata就得到我们所要的像素数据。
第三步,就是将cairodata保存到文件。- FILE* fp = NULL;
- GtkWidget *message_dlg;
- gint return_value;
- gchar **dcharTemp;
- GString *gstringTemp;
- gint i, j, k;
- guchar tempchar[2];
-
- if ((fp = fopen(filename,"rb")) != NULL)
- {
- fclose(fp);
- message_dlg = gtk_message_dialog_new(GTK_WINDOW(NULL),GTK_DIALOG_MODAL,
- GTK_MESSAGE_QUESTION,GTK_BUTTONS_YES_NO,_("Over write the file?"));
- return_value = gtk_dialog_run(GTK_DIALOG(message_dlg));
- gtk_widget_destroy(message_dlg);
- if( return_value != GTK_RESPONSE_YES)
- return -2;
- }
- if ((fp = fopen(filename,"wb")) == NULL)
- {
- // g_warning("error open %s\n",filename);
- message_dlg = gtk_message_dialog_new(GTK_WINDOW(NULL),GTK_DIALOG_MODAL,
- GTK_MESSAGE_INFO,GTK_BUTTONS_OK,_("Can not save file."));
- gtk_dialog_run(GTK_DIALOG(message_dlg));
- gtk_widget_destroy(message_dlg);
- return -1;
- }
- fputs("const unsigned char ",fp);
- dcharTemp = g_strsplit(g_filename_display_basename(filename),".",-1);
- gstringTemp = g_string_new(NULL);
- g_string_printf(gstringTemp,"%s_mark%d[] = {\n",*dcharTemp,width);
- fputs(gstringTemp->str, fp);
- for(i = 0; i < height; i++)
- {
- g_string_free(gstringTemp, TRUE);
- gstringTemp = g_string_new(NULL);
- for(j = 0; j < width; j++)
- {
- pcdata = cairodata + i * cairostride + j * bytesperpixel;
- g_string_append_printf(gstringTemp, "0x%x, 0x%x, 0x%x, 0x%x, ",pcdata[0],pcdata[1],pcdata[2],pcdata[3]);
- }
- g_string_append_printf(gstringTemp, "\n");
- fputs(gstringTemp->str, fp);
- }
- fseek(fp, -3, SEEK_CUR);
- fputs("\n};\n",fp);
- fclose(fp);
- g_string_free(gstringTemp, TRUE);
复制代码 至此,转换功能完成。
下面是如何将数据重现为图片(datatoimg)。
第一步,建立一个新工程,转换生成的*.c(如本例中生成gtk_logo_rgb.c)加到工程中。
第二步,在drawingarea的“expose“回调中重现图片。- cairo_t *cr;
- cairo_surface_t *surface;
- gint cairosurfacex, cairosurfacey;
- gint mark_width = 107;
- gint mark_height = 140;
- gint mark_stride = 428; /* BGRA is 4 channels, so width*channels=107*4=428*/
-
- cr = gdk_cairo_create(widget->window);
- surface = cairo_image_surface_create_for_data(gtk_logo_rgb_mark107,CAIRO_FORMAT_ARGB32,mark_width,mark_height,mark_stride);
- cairosurfacex = MAX (((widget->allocation.width-mark_width)/2), 0);
- cairosurfacey = MAX (((widget->allocation.height-mark_height)/2), 0);
- cairo_set_source_surface (cr, surface, cairosurfacex, cairosurfacey);
- cairo_paint(cr);
- cairo_destroy(cr);
- cairo_surface_destroy(surface);
复制代码
附上源代码,编程环境,windowxp,devcpp,gtk-2.12.9-dev
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?马上加入
x
评分
-
查看全部评分
|