由GdkPixmap得到透明的GdkPixbuf

来源:互联网 发布:晒照片的软件 编辑:程序博客网 时间:2024/06/05 03:46

GdkPixmap得到透明的GdkPixbuf

 

GdkPixmapGdkDrawable的子类。GdkDrawableWin32下的DC(DeviceContext)有点类似,你可以在上面画直线、画圆或者在上面贴图片。DC有很多不同的子类,最常见的有内存DC,打印机DC,屏幕DC。同样,GdkDrawable也有很多子类,非要和Win32对应起来的话,GdkPixmap的地位和内存DC差不多。

 

GdkPixbuf的功能近似于位图(bitmap),但一般仅限于在内存使用中,没有定义特定的存储格式。可以把任意格式的图片文件加裁到一个GdkPixbuf;可以把GdkPixbuf贴到GdkDrawable任意子类的对象上;也可以把GdkDrawable任意子类的对象转换成GdkPixbuf对象,然后把GdkPixbuf对象存为指定格式的图片文件。

 

GTK+提供了几个函数在这两者之间转换:

gdk_draw_pixbuf GdkPixbuf对象贴到GdkDrawable对象上。

gdk_pixbuf_get_from_drawableGdkDrawable对象中得到GdkPixbuf对象。

 

GdkPixmapGdkDrawable的子类,这两个函数自然也适用于GdkPixmap

 

最近遇到一个问题,尽管我指明要透明的GdkPixbuf,通过gdk_pixbuf_get_from_drawable得到的GdkPixbuf仍然是不透明的。

 

GdkPixbuf有一个has_alpha属性,它是控制GdkPixbuf透明与否的第一关。只能在创建时设置它(gdk_pixbuf_new),对于已经存在的GdkPixbuf对象,不能再修改它的has_alpha属性。

 

对于透明的GdkPixbuf,每个像素在内存中占四个字节,也即R(红)、G(绿)、B(蓝)三基色各占一个字节,alpha占一个字节。利用alpha的值可以实现()透明效果,alpha的值为0则完全透明,alpha的值为255则完全不透明,中间的值为半透明。

 

我发现通过gdk_pixbuf_get_from_drawable得到的GdkPixbuf是完全不透明的,从内存中的值可以看到每个像素的alpha值都为255,而且没有任何参数可以控制gdk_pixbuf_get_from_drawable处理透明问题的行为。

 

GTK+提供的相关函数翻了个遍,也没有找到把GdkPixbuf转换为透明效果GdkPixbuf的函数,最后只好自己写了一个,它的缺点是只能指定一种透明色,所有为这种透明色的pixel都是作透明处理。不过,这对正常应用没有什么影响。

 

void

gdk_pixbuf_transparent (GdkPixbuf *pixbuf, guint32   pixel)

{

       guchar *pixels;

       guint r, g, b,a;

       guchar *p;

       guint w, h;

 

       g_return_if_fail (GDK_IS_PIXBUF (pixbuf));

 

       if (pixbuf->width == 0 ||pixbuf->height == 0)

               return;

 

       pixels = pixbuf->pixels;

 

       r = (pixel & 0xff000000) >> 24;

       g = (pixel & 0x00ff0000) >> 16;

       b = (pixel & 0x0000ff00) >> 8;

       a = (pixel & 0x000000ff);

 

       h = pixbuf->height;

 

       while (h--) {

               w = pixbuf->width;

               p = pixels;

 

               switch (pixbuf->n_channels) {

               case 4:

                       while (w--) {

                           if(p[0] ==r && p[1] ==g && p[2] ==b)

                           {

                               p[3] = a;

                           }

                           p += 4;

                       }

                       break;

               default:

                       break;

               }

 

               pixels += pixbuf->rowstride;

       }

 

       return;

}

 

使用方法:

把黑色设置为透明色:gdk_pixbuf_transparent(pixbuf, 0x00000000);

把白色设置为透明色:gdk_pixbuf_transparent(pixbuf, 0xFFFFFF00);

把红色设置为透明色:gdk_pixbuf_transparent(pixbuf, 0xFF000000);

把绿色设置为透明色:gdk_pixbuf_transparent(pixbuf, 0x00FF0000);

把蓝色设置为透明色:gdk_pixbuf_transparent(pixbuf, 0x0000FF00);

原创粉丝点击