graphics-gdk-pixbuf.html

来自「linux下gnome编程」· HTML 代码 · 共 1,729 行 · 第 1/4 页

HTML
1,729
字号
	GDK_PIXBUF_ALPHA_BILEVEL,	GDK_PIXBUF_ALPHA_FULL} GdkPixbufAlphaMode;        </PRE></TD></TR></TABLE><P>          For the time being, for the reasons already stated, you must          always use GDK_PIXBUF_ALPHA_BILEVEL. This value tells          gdk-pixbuf to convert the pixel buffer's alpha channel (if          any) into a 1-bit bilevel mask. When full alpha blending          finally becomes part of the X Window System, you can start          using GDK_PIXBUF_ALPHA_FULL.        </P><P>          So, to render a nonrectangular shape to a drawable, you need          to pass X11 a GdkBitmap instance in addition to your pixel          buffer. If your RGB buffer has an alpha channel, gdk-pixbuf          can take care of the bitmask creation itself, behind the          scenes, using the contents of the alpha channel as a          guide. Sometimes, however, you might want to create the          bitmap yourself, from scratch; perhaps your pixbuf doesn't          have an alpha channel, or you need to do some special          postprocessing to the mask before you render it to a          drawable. If you leave the bitmask creation up to          gdk-pixbuf, you won't be able to step in and alter it be-          fore gdk-pixbuf passes it to X11.        </P><P>          The gdk_pixbuf_render_threshold_alpha( ) function converts a          portion of the pixel buffer's alpha channel into a GdkBitmap          mask provided by you (see Figure 10.8 for a visual          representation of this function):        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">void gdk_pixbuf_render_threshold_alpha(GdkPixbuf *pixbuf,    GdkBitmap *bitmap, int src_x, int src_y,    int dest_x, int dest_y, int width, int height,    int alpha_threshold);        </PRE></TD></TR></TABLE><DIVCLASS="FIGURE"><ANAME="AEN928"></A><P><B>Figure 10-8. Rendering an Alpha Channel to a Bitmap</B></P><DIVCLASS="MEDIAOBJECT"><P><IMGSRC="figures/10f8.png"></IMG></P></DIV></DIV><P>          The src_x and src_y parameters determine where to start in          the source GdkPixbuf; width and height determine the size of          the area to transfer. The dest_x and dest_y parameters          describe where in the destination GdkBitmap to render the          chosen region. If the src coordinates do not match the dest          coordinates, the bitmask will be offset within          GdkBitmap. The GdkBitmap mask can be a different size from          the original pixel buffer, but it must be large enough to          contain the complete mask, including any offsets.        </P><P>          With a little juggling of coordinates, you can take any          rectangular area from the pixel buffer and translate it into          a 1-bit mask of the same size, and then store it anywhere          within GdkBitmap. However, make sure that the bitmap you          pass in is at least (dest_x + width) pixels wide and (dest_y          + height) pixels tall.        </P><P>          The alpha_threshold parameter gives you the critical control          over which pixels to turn on in the bitmask and which to          turn off. As gdk-pixbuf scans through pixels in your alpha          channel, it compares each value to alpha_threshold. If the          alpha channel value is greater than or equal to          alpha_threshold, gdk-pixbuf turns on (sets to 1) the          corresponding bit in the GdkBitmap; any values less than          alpha_threshold are turned off (set to 0).  When the time          comes to render an image with that bitmask, X11 copies only          pixels that are masked to a 1 and ignores the rest. In a          manner of speaking, all areas of the alpha channel that meet          or exceed the threshold are rendered. The higher you set the          alpha_threshold, the less of the image will be rendered.        </P><P>          When your pixel buffer does not contain an alpha channel,          gdk_pixbuf_render_threshold_alpha( ) pretends that the          entire alpha channel is set to 254. Thus if the          alpha_threshold parameter is 0 to 254, the mask will consist          of only 1's, since the alpha channel will be equal to or          above the threshold; everything under that mask will be          visible. If you set alpha_threshold to 255, the mask will be          all 0's, which will hide the entire masked area from view.        </P><P>          When you are done creating your bitmask-which could          conceivably amount to multiple calls to          gdk_pixbuf_render_threshold_alpha( )-you should register it          with the GDK graphics context as a clipping mask, using the          gdk_gc_set_clip_mask( ) function. Later, when GdkRGB renders          the image to the target drawable, it will pull your mask          from the GdkGC structure and use it as a stencil for the          image.        </P><P>          Now that you have a GdkPixbuf structure and a 1-bit mask,          you are ready to transfer the image to a          drawable. Gdk-pixbuf has two functions for rendering to          drawables. The first one, gdk_pixbuf_render_to_drawable( ),          requires that you place the bitmask into a GdkGC structure          beforehand, as already described. The second rendering          function, gdk_pixbuf_render_to_drawable_alpha( ), creates          the bitmask from the alpha channel in the pixel buffer,          internally using gdk_pixbuf_render_threshold_alpha( ):        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">void gdk_pixbuf_render_to_drawable(GdkPixbuf *pixbuf,    GdkDrawable *drawable, GdkGC *gc, int src_x, int src_y,    int dest_x, int dest_y, int width, int height,    GdkRgbDither dither, int x_dither, int y_dither);void gdk_pixbuf_render_to_drawable_alpha(GdkPixbuf *pixbuf,    GdkDrawable *drawable, int src_x, int src_y,    int dest_x, int dest_y, int width, int height,    GdkPixbufAlphaMode alpha_mode, int alpha_threshold,    GdkRgbDither dither, int x_dither, int y_dither);        </PRE></TD></TR></TABLE><P>          The former function gives you more flexibility at the risk          of greater complexity.  You must know how to set up your          bitmask and how to set up a GdkGC structure. The second          function is easier to use but requires a four-channel RGBA          buffer.        </P><P>          For completeness, gdk-pixbuf can transfer images both          ways. Not only can it push a pixel buffer out to a drawable,          but it can also pull a drawable image into a pixel          buffer. This reciprocal capability is perfect for making          screen shots or managing special effects such as zooming in          on another window. The parameters are fairly          straightforward, except for cmap, which is needed only when          the drawable is a GdkPixmap instance, since unlike GdkWindow          structures, pixmaps don't carry their own color maps:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">GdkPixbuf *gdk_pixbuf_get_from_drawable(GdkPixbuf *dest,    GdkDrawable *src, GdkColormap *cmap, int src_x, int src_y,    int dest_x, int dest_y, int width, int height);        </PRE></TD></TR></TABLE></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN943">Scaling</A></H2><P>          If you're lucky, the images you load from graphics files          will be exactly the correct size for what you need. In the          real world, however, you will eventually have to shrink or          enlarge some of your images to a more manageable size. Per-          haps you need a thumbnail of a graphics file or want to          stretch a background to fill a window. Or maybe you just          want to display a collection of images all at the same size          and need to tweak a few of them to fit. Whatever the reason,          image scaling is not something you'll want to tackle from          scratch, unless you are very well versed in graphics          programming. A poorly designed algorithm is guaranteed to          produce noticeable scaling artifacts. Image scaling is a          highly mathematical, deeply researched field of study, and          we are fortunate to have the algorithms for it already coded          and easily accessible in gdk-pixbuf.        </P><P>          The primary scaling function in gdk-pixbuf is          gdk_pixbuf_scale( ), an extremely flexible function that          should cover most, if not all, of your scaling needs. It has          quite a few parameters and can be confusing at first to use:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">void gdk_pixbuf_scale(const GdkPixbuf *src, GdkPixbuf *dest,    int dest_x, int dest_y, int dest_width, int dest_height,    double offset_x, double offset_y, double scale_x,    double scale_y, GdkInterpType interp_type);        </PRE></TD></TR></TABLE><P>          See Figure 10.9 for a visual representation of what the          parameters control.        </P><DIVCLASS="FIGURE"><ANAME="AEN949"></A><P><B>Figure 10-9. Scaling Parameters</B></P><DIVCLASS="MEDIAOBJECT"><P><IMGSRC="figures/10f9.png"></IMG></P></DIV></DIV><P>          The src pixbuf is the base unscaled image-for example, the          graphics file you just loaded into memory. The dest pixbuf          is the preexisting target for rendering the scaled          image. The scale_x and scale_y parameters are the scaling          multipliers; a value less than 1.0 will shrink the image,          and a value greater than 1.0 will enlarge it. A (scale_x,          scale_y) value of (2.0, 0.5) will make the src pixel buffer          twice as wide and only half as tall. Gdk-pixbuf will scale          the entire src pixbuf by these multipliers. You can then use          offset_x and offset_y to move the scaled image in relation          to the destination origin at (dest_x, dest_y).        </P><P>          In its final step, gdk_pixbuf_scale( ) copies the area          defined by the four dest_* parameters to the dest pixbuf. In          other words, gdk_pixbuf_scale( ) scales src by (scale_x,          scale_y), moves it to (offset_x, offset_y), and takes a          snapshot of it using the rectangle defined by (dest_x,          dest_y, dest_width, dest_height). By cleverly manipulating          the size and position parameters, you can selectively copy          any portion of the scaled src pixbuf. In Figure 10.9 we pass          in an offset_x of -10.0 to shift the image 10 pixels to the          left so that it's centered in the 30-pixel-wide clipping          region in the destination pixbuf.        </P><P>          You must create the dest pixbuf beforehand. You should be          careful to create one large enough to hold the scaled          image. Always make dest at least (dest_x + dest_width)          pixels wide and (dest_y + dest_height) pixels tall.        </P><P>          The last parameter, interp_type, determines which scaling          algorithm you want to use. Each of the four algorithms          varies in quality, speed, and appearance, so you should          pick the filtering style that best suits your needs. GdkIn-          terpType is an enumeration of the available algorithms:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">typedef enum{  GDK_INTERP_NEAREST,  GDK_INTERP_TILES,  GDK_INTERP_BILINEAR,  GDK_INTERP_HYPER} GdkInterpType;        </PRE></TD></TR></TABLE><P>          The enumeration represents the order of increasing quality          (and increased rendering time) of the filter          operations. GDK_INTERP_NEAREST is by far the quickest, but          it ends up rather pixelated for enlargements.          GDK_INTERP_BILINEAR uses bilinear interpolation to produce          smooth, antialiased scaled images, even when you magnify          the image to many times its original size. Between NEAREST          and BILINEAR is GDK_INTERP_TILES, which looks pixelated like          NEAREST when you enlarge but is smoother when you shrink the          image, like BILINEAR. GDK_INTERP_HYPER is the          highest-quality filter, and of course the slowest. In most          cases, TILES and BILINEAR will be good enough.        </P><P>          Often you won't need to use all the various parameters in          gdk_pixbuf_scale( ), and they will just get in the          way. Fortunately, gdk-pixbuf also has a streamlined          version: gdk_pixbuf_scale_simple( ). Gone are the offsets          and scaling factors, which are either set to 0 or calculated          from the size of the src pixbuf. This function will scale          the entire src image to the new size of dest_width          dest_height and create a GdkPixbuf instance containing the          scaled image, saving you from creating a properly sized dest          pixbuf yourself:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">GdkPixbuf *gdk_pixbuf_scale_simple(const GdkPixbuf *src,    int dest_width, int dest_height,    GdkInterpType interp_type);        </PRE></TD></TR></TABLE><P>          The two scaling functions we've covered so far will erase          the previous contents of the destination pixel buffer          (although technically the internally created destination          pixel buffer in gdk_pixbuf_scale_simple( ) will always be          initially empty, making this a moot point). Sometimes you'll          need to overlay the scaled image on top of an existing          image without entirely overwriting it, a process known as          compositing. The gdk-pixbuf function to do alpha blending          like this is gdk_pixbuf_composite( ). It is similar to          gdk_pixbuf_scale( ) except for the extra parameter,          overall_alpha, which it uses to determine the opacity of the          scaled image:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">void gdk_pixbuf_composite(const GdkPixbuf *src, GdkPixbuf *dest,    int dest_x, int dest_y, int dest_width, int dest_height,    double offset_x, double offset_y, double scale_x,    double scale_y, GdkInterpType interp_type,    int overall_alpha);        </PRE></TD></TR></TABLE><P>          The dest pixbuf should already have image data in it;          otherwise, what's the point of compositing the scaled src          image on top of it?        </P><P>          Incidentally, gdk-pixbuf has a couple of other more          specialized scaling and compositing functions:          gdk_pixbuf_composite_color( ) and the slimmer version,          gdk_pixbuf_composite_color_simple( ). Rather than          compositing the scaled image onto another image, these          functions will composite it onto a generated checkerboard          pattern. This functionality is probably not useful to you          unless you are writing an application for viewing or editing          anti-aliased images. The checkerboard pattern helps          emphasize the anti-aliasing.  Figure 10.10 shows          testpixbuf-scale, one of the test programs that comes with          gdk-pixbuf, using gdk_pixbuf_composite_color( ) to display          gnome-globe.png, an icon packaged with gnome-libs.        </P><DIVCLASS="FIGURE"><ANAME="AEN966"></A><P><B>Figure 10-10. Image Composition with testpixbuf-scale</B></P><DIVCLASS="MEDIAOBJECT"><P><IMGSRC="figures/10f10.png"></IMG></P></DIV></DIV><P>          A specialization of the scaling operation is the copy          operation, in which the scaling multipliers are both          1.0. Rather than forcing you to call gdk_pixbuf_scale( )          with a one-to-one scaling ratio, gdk-pixbuf offers a con-          venience function to do it in a more rational way:          gdk_pixbuf_copy_area( ).  This function copies the region

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?