Re: getting color from gdk::pixbuf (probably a bug in Gdk::Pixbuf)
- From: "muppet" <scott asofyet org>
- To: gtk-perl-list gnome org
- Subject: Re: getting color from gdk::pixbuf (probably a bug in Gdk::Pixbuf)
- Date: Wed, 3 Mar 2004 11:36:52 -0500 (EST)
doome said:
Is it possible that the get_pixels function doesn't work?
The get_pixels function returns nothing, however the png image shows up
in the Gtk2::Image.
...
The $image shows up in the window, but the $pixels string is empty.
It works, but it's being fooled. I bet the first pixel in your image has a
value of 0 for the red channel, doesn't it? 0 is the null terminator for
strings, so the output typemap for the get_pixels binding is just giving you
an empty string.
I tried it with a different image and got about a quarter of the image data
--- up until it hit a 0.
The solution is this patch, which will be applied to HEAD in just a few minutes:
Index: xs/GdkPixbuf.xs
===================================================================
RCS file: /cvsroot/gtk2-perl/gtk2-perl-xs/Gtk2/xs/GdkPixbuf.xs,v
retrieving revision 1.28
diff -u -r1.28 GdkPixbuf.xs
--- xs/GdkPixbuf.xs 23 Feb 2004 19:35:27 -0000 1.28
+++ xs/GdkPixbuf.xs 3 Mar 2004 15:58:33 -0000
@@ -212,9 +212,18 @@
GdkPixbuf *pixbuf
## guchar *gdk_pixbuf_get_pixels (const GdkPixbuf *pixbuf)
-guchar *
+SV *
gdk_pixbuf_get_pixels (pixbuf)
GdkPixbuf *pixbuf
+ PREINIT:
+ guchar * pixels;
+ CODE:
+ pixels = gdk_pixbuf_get_pixels (pixbuf);
+ RETVAL = newSVpv (pixels,
+ gdk_pixbuf_get_height (pixbuf)
+ * gdk_pixbuf_get_rowstride (pixbuf));
+ OUTPUT:
+ RETVAL
## int gdk_pixbuf_get_width (const GdkPixbuf *pixbuf)
int
With that patch, the following code works fine (and is pretty cool, too).
-=-=-
#!/usr/bin/perl
use strict;
use warnings;
use Glib qw(FALSE TRUE);
use Gtk2 -init;
die "Usage: $0 imagefile\n" unless @ARGV;
my $pixbuf = Gtk2::Gdk::Pixbuf->new_from_file ($ARGV[0]);
my $pixels = $pixbuf->get_pixels;
print "length: ".length($pixels)."\n";
foreach my $attr (qw/width height rowstride n_channels has_alpha/) {
my $sym = "get_$attr";
print "$attr: ".($pixbuf->$sym ())."\n";
}
my $l = $pixbuf->get_height * $pixbuf->get_rowstride;
print "calculated length: $l\n";
my $window = Gtk2::Window->new;
my $hbox = Gtk2::HBox->new;
my $ebox = Gtk2::EventBox->new;
my $vbox2 = Gtk2::VBox->new;
my $image = Gtk2::Image->new_from_pixbuf ($pixbuf);
my $frame = Gtk2::Frame->new ('Color');
my $vbox = Gtk2::VBox->new;
my $label = Gtk2::Label->new;
my $darea = Gtk2::DrawingArea->new;
$darea->set_size_request (64, 64);
$window->add ($hbox);
$ebox->add ($image);
$vbox2->pack_start ($ebox, TRUE, FALSE, 0);
$hbox->pack_start ($vbox2, TRUE, FALSE, 0);
$hbox->pack_start ($frame, FALSE, FALSE, 0);
$frame->add ($vbox);
$vbox->pack_start ($label, FALSE, FALSE, 0);
$vbox->pack_start ($darea, FALSE, FALSE, 0);
$window->set_title ("Color Snooper");
$window->show_all;
$window->signal_connect (delete_event => sub {Gtk2->main_quit;});
$ebox->window->set_cursor (create_cursor());
$ebox->add_events (['pointer-motion-mask', 'pointer-motion-hint-mask']);
$ebox->signal_connect (motion_notify_event => sub {
my ($widget, $event) = @_;
$widget->window->get_pointer;
my ($x, $y) = $widget->translate_coordinates ($image,
$event->x, $event->y);
my ($r, $g, $b, $a) =
unpack "C*",
substr $pixels,
$pixbuf->get_rowstride * $y
+ $pixbuf->get_n_channels * $x,
$pixbuf->get_n_channels;
$label->set_text ("x,y: ".$event->x.", ".$event->y."\n"
."R: $r\n"
."G: $g\n"
."B: $b"
.($pixbuf->get_has_alpha ? "\nA: $a" : ""));
my $color = Gtk2::Gdk::Color->new ($r << 8, $g << 8, $b << 8);
$darea->modify_bg ('normal', $color);
$darea->queue_draw;
});
Gtk2->main;
sub create_cursor {
# these icons borrowed from the gimp.
use constant dropper_small_width => 32;
use constant dropper_small_height => 32;
use constant dropper_small_x_hot => 13;
use constant dropper_small_y_hot => 30;
my $dropper_small_bits = pack 'C*',
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x41,
0x00, 0x00, 0xc0, 0xa1, 0x00, 0x00, 0x20, 0xbc, 0x00, 0x00, 0x40, 0xbb,
0x00, 0x00, 0x80, 0x44, 0x00, 0x00, 0x40, 0x34, 0x00, 0x00, 0x20, 0x13,
0x00, 0x00, 0x90, 0x15, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x64, 0x00,
0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x80, 0x0c, 0x00,
0x00, 0x40, 0x06, 0x00, 0x00, 0x40, 0x03, 0x00, 0x00, 0xe0, 0x01, 0x00,
0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00;
my $dropper_small_mask_bits = pack 'C*',
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x7f,
0x00, 0x00, 0xc0, 0xff, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0xc0, 0xff,
0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0xf0, 0x1f,
0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0xfe, 0x00,
0x00, 0x00, 0x7f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0xc0, 0x1f, 0x00,
0x00, 0xe0, 0x0f, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xf0, 0x03, 0x00,
0x00, 0xe0, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00;
my $icon = Gtk2::Gdk::Bitmap->create_from_data (undef, $dropper_small_bits,
dropper_small_width, dropper_small_height);
my $mask = Gtk2::Gdk::Bitmap->create_from_data (undef,
$dropper_small_mask_bits, dropper_small_width, dropper_small_height);
return Gtk2::Gdk::Cursor->new_from_pixmap
($icon, $mask,
Gtk2::Gdk::Color->new (0, 0, 0),
Gtk2::Gdk::Color->new (65535, 65535, 65535),
dropper_small_x_hot, dropper_small_y_hot);
}
-=-=-=-
--
muppet <scott at asofyet dot org>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]