graphics-gdk-pixbuf.html

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

HTML
1,729
字号
          defined by src_x, src_y, width, and height in the source          pixel buffer, into the destination pixel buffer at (dest_x,          dest_y):        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">void gdk_pixbuf_copy_area(const GdkPixbuf *src_pixbuf,    int src_x, int src_y, int width, int height,    GdkPixbuf *dest_pixbuf, int dest_x, int dest_y);        </PRE></TD></TR></TABLE></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN973">Progressive Loading</A></H2><P>          Gdk-pixbuf's image-loading facilities make it very easy for          you to load a variety of graphics file formats without doing          any extra work. All you have to do is supply the file name,          and gdk-pixbuf will handle the rest. However, the file-          loading system has one potentially limiting flaw: It blocks          until it's finished.  With icons and smaller images, this          temporary stall is not noticeable enough to matter, but when          the file is particularly large, or is loading from a remote          site with a slow connection, your application may flounder          in an input/output loop, unable to update itself. The          resulting slowness gives your application a buggy,          unresponsive appearance, even though it has a good reason          for stalling.        </P><P>          To address this problem, the gdk-pixbuf library offers the          GdkPixbufLoader API. GdkPixbufLoader is a derivative of          GtkObject that allows the loading process to be controlled          by your application rather than by gdk-pixbuf's          image-loading code. Because it's derived from GtkObject,          GdkPixbufLoader can notify you through GTK+ signals when          something interesting happens.        </P><P>          The interface is simple and straightforward. You create a          loader object, write chunks of raw image data to it, and          then close it when you're done. As soon as the loader          receives enough of the graphics file to determine what sort          of image it's loading, it creates a GdkPixbuf structure in          which to store the image data. When you close the loader, it          unreferences that GdkPixbuf, so if you want the pixbuf still          to exist after you're done with the loader, your appli-          cation will need to explicitly call gdk_pixbuf_ref( ) on it          (and of course release it when you're done). The best          place to reference the pixbuf is inside an area_prepared          signal callback, which we'll discuss in a moment.        </P><P>          The loader uses the same code to load images into          GdkPixbufLoader that gdk-pixbuf uses inside          gdk_pixbuf_new_from_file( ). Here's the basic          GdkPixbufLoader API:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">GdkPixbufLoader* gdk_pixbuf_loader_new(  );gboolean gdk_pixbuf_loader_write(GdkPixbufLoader *loader,    const guchar *buf, size_t count);GdkPixbuf* gdk_pixbuf_loader_get_pixbuf(    GdkPixbufLoader *loader);void gdk_pixbuf_loader_close(GdkPixbufLoader *loader);        </PRE></TD></TR></TABLE><P>          The loader has three signals of interest to us here.3 Here          are the prototypes for these signals, from the          GdkPixbufLoaderClass structure:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">void (* area_prepared) (GdkPixbufLoader *loader);void (* area_updated) (GdkPixbufLoader *loader,    guint x, guint y, guint width, guint height);void (* closed) (GdkPixbufLoader *loader);        </PRE></TD></TR></TABLE><P>          The aforementioned area_prepared signal indicates that the          loader has read enough of the file to calculate the size and          color depth of the image.  Until the loader has this          information, it makes no sense to create the target          GdkPixbuf. This first milestone is important enough to merit          a special signal emission because it means that your          application can allocate space in the display for the          image. If you connect to the area_prepared signal, you          should take the opportunity in your callback to call          gdk_pixbuf_ref( ) on the supplied pixbuf. Also, you are          guaranteed at this point that the loader has not started          writing into the new pixel buffer, so you can fill it with          whatever background you want, whether it's a solid color          or a placeholder image. As image data continues to pour into          the loader, your background image will slowly be written          over, line by line, until the full image arrives.        </P><P>          You'll receive only one area_prepared signal per loader, but          altogether you'll end up receiving several area_updated          signals. In fact, each time you call          gdk_pixbuf_loader_write( ), the loader will fire off another          area_updated signal. If you're displaying the progressive          image to a drawable-which, after all, is largely the point          of using GdkPixbufLoader- you should use this opportunity to          update the display. In the sample application at the end of          this chapter, we do this by copying the currently loaded          portion of the image to a GdkPixmap drawable with          gdk_pixbuf_render_to_drawable_alpha( ) and then triggering a          refresh with gtk_widget_draw( ).        </P><P>          The final signal, closed, is useful if you want to know when          the image is completely loaded. If other parts of your          application, such as a Web browser window, need to be          notified when the image is complete, you can connect them to          the loader's closed signal, rather than blocking until then.        </P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN985">Autoconf Support</A></H2><P>          To facilitate its integration with the GNOME build system,          the gdk-pixbuf package contains an autoconf macro, a          gdk-pixbuf-config tool, and a drop-in extension for          gnome-config.        </P><P>          You can use the macro AM_PATH_GDK_PIXBUF in your          configure.in file to run a series of checks for          gdk-pixbuf. It works just as you would expect: You give it          the minimum version of gdk-pixbuf your application requires,          followed by an optional shell-scripted action to perform if          the target system has a valid gdk-pixbuf installation, and a          second action to perform if the target system fails the          test:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">AM_PATH_GDK_PIXBUF([MINIMUM-VERSION, [ACTION-IF-FOUND  [, ACTION-IF-NOT-FOUND]]])        </PRE></TD></TR></TABLE><P>          The macro will call AC_SUBST on the GDK_PIXBUF_CFLAGS and          GDK_PIXBUF_LIBS variables, which you can then reference from          your Makefile.am file. It also runs some safety checks to          alert the administrator of any strange behavior in the          current gdk-pixbuf installation. Finally, it adds the          options --with-gdk-pixbuf-prefix and          --with-gdk-pixbuf-exec-prefix to the configure script to          handle cases in which gdk-pixbuf is installed in a          nonstandard place on the target system.        </P><P>          Gdk-pixbuf supplies its own version of gnome-config, called          gdk-pixbuf-config, for retrieving path and version          information at the command line. It also installs a plug-in          extension so that you can get the same information from          gnome-config. You can run either one of these commands to          obtain the necessary CFLAGS parameters for gdk-pixbuf:        </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">gnome-config gdk_pixbuf --cflagsgdk-pixbuf-config --cflags        </PRE></TD></TR></TABLE></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN993">Gdk-pixbuf Application Example</A></H2><P>          In our sample graphics application, we will touch on many          points related to what we've just been discussing. We will          see how to create a GdkPixbuf structure from a file and          from an existing raw buffer. We will see how to copy image          data from buffer to buffer, and from buffer to GDK          drawable. We'll dip into image scaling and compositing,          event handling, and even progressive image loading. To top          things off, we'll include double buffering with a GdkPixmap.        </P><P>          Although this example is technically a GNOME application,          most of it consists of calls to GDK and gdk-pixbuf. You can          click on two of the icons (see Figure 10.11). Clicking on          the feather will change the alpha blending level and make          the feather fade in and out of view; clicking on the icon          for gnome-error.png will load an image of a globe, a few          scan lines at a time.  Figure 10.11 shows a screen shot of          the sample application. Listings 10.1 and 10.2 contain the          makefile and the source code.        </P><DIVCLASS="FIGURE"><ANAME="AEN997"></A><P><B>Figure 10-11. Screen Shot of Sample Gdk-pixbuf Application</B></P><DIVCLASS="MEDIAOBJECT"><P><IMGSRC="figures/10f11.png"></IMG></P></DIV></DIV><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 10.1 Makefile for Sample Gdk-pixbuf ApplicationCC = gcc CFLAGS = `gnome-config --cflags gnomeui gdk_pixbuf`LDFLAGS = `gnome-config --libs gnomeui gdk_pixbuf`rgbtest: rgbtest.c        $(CC) rgbtest.c -o rgbtest $(CFLAGS) $(LDFLAGS)        </PRE></TD></TR></TABLE><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">Listing 10.2 Source Code for Sample Gdk-pixbuf Application/* rgbtest.c - Sample gdk-pixbuf Application */#include &#60;gnome.h&#62;#include &#60;gdk-pixbuf/gdk-pixbuf.h&#62;#include &#60;gdk-pixbuf/gdk-pixbuf-loader.h&#62;#include &#60;unistd.h&#62;#include &#60;sys/stat.h&#62;#define PACKAGE "rgbtest"#define VERSION "0.0.1"/* Size of drawing area */#define WIDTH 250#define HEIGHT 200/* Coordinates of progressive loader image */#define LOADER_X 100#define LOADER_Y 140/* Visible drawing surface */GtkWidget *drawing_area;/* Raw pixel buffer */static guchar drawbuf[WIDTH * HEIGHT * 6];/* Double-buffer pixmap */GdkPixmap *dbuf_pixmap = NULL;/* Feather opacity */static gint opacity = 127;/* Loader stuff */GdkPixbufLoader *loader = NULL;GdkPixbuf *loader_pixbuf = NULL;guchar *filebuf = NULL;guint filesize = 0;guint curpos = 0;/* Create a colorful background gradient */static void init_drawing_buffer(  ){  gint x, y;  gint pixel_offset;  gint rowstride = WIDTH * 3;  for (y = 0; y &#60; HEIGHT; y++)  {    for (x = 0; x &#60; WIDTH; x++)    {      pixel_offset = y * rowstride + x * 3;      drawbuf[pixel_offset] = y * 255 / HEIGHT;      drawbuf[pixel_offset + 1] = 128 - (x + y) * 255 /        (WIDTH * HEIGHT);      drawbuf[pixel_offset + 2] = x * 255 / WIDTH;    }  }}/* Render our images to the double-buffered pixmap */static void render_apples(  ){  gint width;  gint height;  GdkPixbuf *pixbuf1, *pixbuf2, *pixbuf3;  gchar *applefile = gnome_pixmap_file ("apple-red.png");  if(applefile)  {    g_message ("Rendering apple: %s", applefile);    pixbuf1 = gdk_pixbuf_new_from_file(applefile);    width = gdk_pixbuf_get_width(pixbuf1);    height = gdk_pixbuf_get_height(pixbuf1);    /* Scale second apple to double size */    pixbuf2 = gdk_pixbuf_scale_simple(pixbuf1, width * 2,      height * 2, GDK_INTERP_BILINEAR);    /* Create a 50 x 180 GdkPixbuf to display our distorted     * apple. Set the dest parameters to copy into the full      * area of pixbuf3. Offset the chunk of pixbuf1 that we're     * scaling by (-50.0, -60.0) so that we see an interesting     * bit of the stem, and not just the upper left-hand corner     * of the apple. Finally, stretch the apple by 4 in the     * horizontal and 12 in the vertical.     */    pixbuf3 = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,      50, 180);    gdk_pixbuf_scale(pixbuf1, pixbuf3,      0, 0, 50, 180,      -50.0, -60.0,      4.0, 12.0,      GDK_INTERP_BILINEAR);    gdk_pixbuf_render_to_drawable_alpha(pixbuf1, dbuf_pixmap,      0, 0, 50, 0, width, height,      GDK_PIXBUF_ALPHA_BILEVEL, 128,      GDK_RGB_DITHER_NORMAL, 0, 0);    gdk_pixbuf_render_to_drawable_alpha(pixbuf2, dbuf_pixmap,      0, 0, 70, 20, width * 2, height * 2,      GDK_PIXBUF_ALPHA_BILEVEL, 128,      GDK_RGB_DITHER_NORMAL, 0, 0);    gdk_pixbuf_render_to_drawable_alpha(pixbuf3, dbuf_pixmap,      0, 0, WIDTH - 70, 0, 50, 180,      GDK_PIXBUF_ALPHA_BILEVEL, 128,      GDK_RGB_DITHER_NORMAL, 0, 0);    gdk_pixbuf_unref(pixbuf1);    gdk_pixbuf_unref(pixbuf2);    gdk_pixbuf_unref(pixbuf3);    g_free(applefile);  }}static void render_feathers(  ){  gint width;  gint height;  GdkPixbuf *pixbuf1, *pixbuf2;  gchar *featherfile = gnome_pixmap_file ("gnome-word.png");  if(featherfile)  {    g_message ("Rendering feather: %s", featherfile);    pixbuf1 = gdk_pixbuf_new_from_file(featherfile);    width = gdk_pixbuf_get_width(pixbuf1);    height = gdk_pixbuf_get_height(pixbuf1);    /* Create a feather composited onto a checkerboard */    pixbuf2 = gdk_pixbuf_composite_color_simple(pixbuf1,

⌨️ 快捷键说明

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