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