Re: gdk-pixbuf: rotate?



Libart seemed a little heavy, so I did this:

/* rotates 24-bit gdkpixbuf 180 degrees */
char *rotate_180(char *buf, int len)
{
        int     x,y,z;
        char    t;
        char    *out;
        int pixels;
        out=(char *)malloc(128+sizeof(char)*len);
        memset(out,0,128+sizeof(char)*len);
        pixels=len/3;
        printf("rotating %d bytes of image data\n",len);
        for (z=0; z<pixels; z++)
        {
                x=z*3;
                for(y=0;y<3;y++)
                {
                        out[x+y]=buf[len-x+y];
                };
        };
        printf("done\n");
        return out;
}

... I pass it the output of gdk_pixbuf_get_pixels(mypixmaparea) and then
wrap the output into a pixbuf with gdk_pixbuf_new_from_data().

... now, for MMX... 

oh wait, I'm not a masochist.

-M

josh wrote:

Michael Rothwell wrote:

With gdkpixbuf, I can copy one pixbuf onto an area of another. Is there
a way to also rotate it? I need to do a 180-degree rotate before or
during (or even after) the overlay.

You need to use the libart-lgpl functions (which I think underly
GdkPixbuf) directly.  With libart you can perform general affine
transformations including rotations.  To use this with GdkPixbuf you
need to dump the pixbuf into a packed rgb.

Here's a simple example which loads an image into a pixbuf, scales it by
a factor of two, performs a rotation ccw by 30 degrees, and composes it
onto a black (the g_new0 commands initializes our data to 0) background.

There's no docs I know of except directly in the source for libart_lgpl,
so have a look at the files in CVS, for example:

http://cvs.gnome.org/lxr/source/libart_lgpl/art_affine.c

josh

/* libart_example.c
 *
 * Copyright (C) 2000 josh buhl <jbuhl users sourceforge net>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program (see the file COPYING); if not, write to
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA
 *
 * Some of this code is from `Wanda-the-Fish' applet code by George Lebl
 * (C) 1998 The Free Software Foundation.
 */

#include <gtk/gtk.h>
#include <gnome.h>
#include <gdk-pixbuf/gdk-pixbuf.h>

#include <libart_lgpl/art_alphagamma.h>
#include <libart_lgpl/art_filterlevel.h>
#include <libart_lgpl/art_pixbuf.h>
#include <libart_lgpl/art_rgb_pixbuf_affine.h>
#include <libart_lgpl/art_affine.h>
#include <libart_lgpl/art_rgb.h>
#include <libart_lgpl/art_rgb_affine.h>
#include <libart_lgpl/art_rgb_rgba_affine.h>

#define IMAGE_WIDTH      256
#define IMAGE_HEIGHT     256

GtkWidget *blah_window;
GtkWidget *blah_darea;

static void
load_image(gchar *pixmap)
{
    GdkPixbuf *pixbuf;
            int x, y, h, w;

    pixbuf = gdk_pixbuf_new_from_file(pixmap);
    if(pixbuf) {
        double affine[6];
        guchar *rgb;

        gint width, height;

        width = gdk_pixbuf_get_width (pixbuf);
        height = gdk_pixbuf_get_height (pixbuf);

        h=IMAGE_HEIGHT;
        w=IMAGE_WIDTH;

        affine[0] = 0.866*2.0; /* = 2*cos(30) */
        affine[2] = 0.5*2.0; /* = 2*sin(30) */
        affine[3] = 0.866*2.0; /* = 2*cos(30) */
        affine[1] = -0.5*2.0; /* = -2*sin(30) */

        affine[4] = 80; /* x translation */
        affine[5] = 128; /* y translation */

        rgb = g_new0(guchar,w*h*3);

        if (gdk_pixbuf_get_has_alpha (pixbuf)) {
            art_rgb_rgba_affine (rgb, 20, 20, w,h, w * 3,
                                 gdk_pixbuf_get_pixels (pixbuf),
                                 width, height,
                                 gdk_pixbuf_get_rowstride (pixbuf),
                                 affine,
                                 ART_FILTER_NEAREST,
                                 NULL);

        } else {
            art_rgb_affine (rgb,
                            0, 0, w, h, w * 3,
                            gdk_pixbuf_get_pixels (pixbuf),
                            width, height,
                            gdk_pixbuf_get_rowstride (pixbuf),
                            affine,
                            ART_FILTER_NEAREST,
                            NULL);
        }

        gdk_draw_rgb_image(blah_darea->window,
                           blah_window->style->fg_gc[GTK_STATE_NORMAL],
                           0, 0, w, h, GDK_RGB_DITHER_NORMAL,
                           rgb, w*3);

        gdk_pixbuf_unref(pixbuf);
        g_free(rgb);
    }

}

static void destroy_cb(GtkWidget * widget, gpointer data)
{
        gtk_widget_destroy(widget);
        gtk_main_quit();

        return;
}

int main (int argc, char **argv)
{
    gchar *file;

    gtk_init(&argc, &argv);

    gdk_rgb_init();

    gtk_widget_push_visual (gdk_rgb_get_visual ());
    gtk_widget_push_colormap (gdk_rgb_get_cmap ());

    blah_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    blah_darea = gtk_drawing_area_new();
    gtk_drawing_area_size (GTK_DRAWING_AREA (blah_darea), IMAGE_WIDTH,
IMAGE_HEIGHT);
    gtk_container_add(GTK_CONTAINER(blah_window),blah_darea);
    gtk_widget_show_now(blah_darea);
    gtk_widget_show_now(blah_window);

    gtk_widget_pop_colormap ();
    gtk_widget_pop_visual ();

    file = gnome_unconditional_pixmap_file ("apple-red.png");

    load_image(file);

    gtk_signal_connect(GTK_OBJECT(blah_window), "destroy",
                       GTK_SIGNAL_FUNC(destroy_cb), NULL);

    gtk_main ();

    return 0;

}

--
"I'll rob that rich person and give his gold to some poor undeserving
slob.  That will *prove* I'm Robin Hood."
        -- Daffy Duck, "Robin Hood Daffy", [1958, Chuck Jones]

_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list gnome org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]