将图片转换成C语言数据文件,然后在程序中调用重现图片
将图片转换为数据(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 = pdata;
pcdata = pdata;
pcdata = pdata;
if(n_channels == bytesperpixel)
pcdata = pdata;
}
}
至此cairodata就得到我们所要的像素数据。
第三步,就是将cairodata保存到文件。
FILE* fp = NULL;
GtkWidget *message_dlg;
gint return_value;
gchar **dcharTemp;
GString *gstringTemp;
gint i, j, k;
guchar tempchar;
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,pcdata,pcdata,pcdata);
}
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
学习 学习啊 想学 谢谢 学习了
页:
[1]