Hi, I'm trying to write my own pixel values to a GdkPixbuf in a GtkImage widget. I've attached the source file for my program, which doesn't seem to do anything. The function for modifying the pixel values is a slightly modified version of the one found on the GdkPixbuf documentation page, http://developer.gnome.org/gdk-pixbuf/unstable//gdk-pixbuf-The-GdkPixbuf-Structure.html Can someone explain to me if there's anything I'm doing wrong with the pixel information? Paul Khermouch pkhermouch gmail com
Attachment:
box.jpg
Description: JPEG image
#include <gtk/gtk.h> #include <gdk-pixbuf/gdk-pixbuf.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #define WINDOW_WIDTH 600 #define WINDOW_HEIGHT 600 GtkWidget* window; GtkWidget* image; char changed; char DEBUG; static gboolean close_window(GtkWidget* widget, GdkEvent* event, gpointer data); static void destroy(GtkWidget *widget, gpointer data); static guint snooper(GtkWidget* widget, GdkEventKey* event, gpointer data); static void configure_pixbuf(); static void draw_pixel(int x, int y, guchar red, guchar green, guchar blue); int main(int argc, char* argv[]) { changed = 0; DEBUG = (argc > 1); // Initialize the gtk session. gtk_init(&argc, &argv); // Create a new window, set the title, size and icon, // and make the window non-resizeable. window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Image Display"); //gtk_widget_set_size_request(GTK_WIDGET(window), WINDOW_WIDTH, WINDOW_HEIGHT); gtk_window_set_resizable(GTK_WINDOW(window), FALSE); // Link the "delete-event" signal, caused by clicking the X on the // title bar, to the close_window() function. g_signal_connect(window, "delete-event", G_CALLBACK(close_window), NULL); // Link the "destroy" signal, caused when we return FALSE in // close_window(), to the destroy() function. g_signal_connect(window, "destroy", G_CALLBACK(destroy), NULL); // Intercept key presses before the events occur. This will allow // us to move the images upon key presses while allowing the user to // enter text into the entry widget. gtk_key_snooper_install((GtkKeySnoopFunc) snooper, NULL); image = gtk_image_new_from_file("box.jpg"); gtk_container_add(GTK_CONTAINER(window), image); // Display all of the widgets. gtk_widget_show(image); gtk_widget_show(window); g_print("Finished adding everything, calling gtk_main()\n"); // Call gtk_main() to start up the GUI. gtk_main(); return 0; } // Called when the user clicks the X button on the toolbar. static gboolean close_window(GtkWidget* widget, GdkEvent* event, gpointer data) { // Return FALSE and the main window will emit the // "destroy" signal and call the destroy() function. // Return TRUE to indicate you don't want to destroy // the window after this function call, useful for // "Are you sure you want to quit?" dialogs. return FALSE; } // Called when the above function returns FALSE. static void destroy(GtkWidget *widget, gpointer data) { gtk_main_quit(); } // Keyboard snooper function. static guint snooper(GtkWidget* widget, GdkEventKey* event, gpointer data) { if (event->keyval == 'q') { exit(0); } if (changed) { g_print("Image has already been modified\n"); return 0; } GdkPixbuf *pixbuf; unsigned int width, height; guchar *pixelstream; int counter; pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(image)); if (event->type == GDK_KEY_PRESS) { width = (unsigned int) gdk_pixbuf_get_width(pixbuf); height = (unsigned int) gdk_pixbuf_get_height(pixbuf); pixelstream = gdk_pixbuf_get_pixels(pixbuf); printf("width %u height %u\n", width, height); // Draw some pixels. for (counter = 0; counter < width; counter++) { draw_pixel(counter % width, height / 2, 255, 0, 0); } g_print("Changed the pixels?\n"); changed = 1; } return 0; } static void configure_pixbuf() { GdkPixbuf *pixbuf; pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(image)); // Already the default value. if (gdk_pixbuf_set_option(pixbuf, "bits-per-sample", 8) == FALSE) { printf("gdk_pixbuf_set_option() failed\n"); } } static void draw_pixel(int x, int y, guchar red, guchar green, guchar blue) { int width, height, rowstride, n_channels; guchar *pixels, *p; GdkPixbuf *pixbuf; pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(image)); n_channels = gdk_pixbuf_get_n_channels(pixbuf); // Check that the way of storing the pixel data // is the way we want. g_assert(gdk_pixbuf_get_colorspace(pixbuf) == GDK_COLORSPACE_RGB); g_assert(gdk_pixbuf_get_bits_per_sample(pixbuf) == 8); g_assert(gdk_pixbuf_get_has_alpha(pixbuf) == FALSE); g_assert(n_channels == 3); width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); g_assert (x >= 0 && x < width); g_assert (y >= 0 && y < height); rowstride = gdk_pixbuf_get_rowstride (pixbuf); pixels = gdk_pixbuf_get_pixels (pixbuf); p = pixels + y * rowstride + x * n_channels; DEBUG && printf("draw_line: width %d height %d x %d y %d\n", width, height, x, y); DEBUG && printf("array beginning: %lu, rowstride: %d, p: %lu\n", (long unsigned) pixels, rowstride, (long unsigned) p); p[0] = red; p[1] = green; p[2] = blue; }
Attachment:
makefile
Description: Binary data