Re: Resize Pixbuf



On Wed, May 11, 2005 at 08:21:24PM +0200, A. Pagaltzis wrote:

I tried it with using the size_allocate signal, but this
creates infinite loops because
$image->set_from_pixbuf($pixbuf), which is called from my
signal handler, itself emits an size_allocate signal. 

Block the signal handler. When you connect a signal handler, you
get a numeric ID for that connection. Pass this to
->signal_handler_block() before calling the function that causes
the signal, then pass it to ->signal_handler_unblock().

I tried it this way, but it doesn't stop the infinite loops. Here is the
code i have, maybe it helps you to sort things out.



#!/usr/bin/perl

use strict;
use Glib qw(TRUE FALSE);
use Gtk2 -init;
use Gtk2::Gdk::Keysyms;

my $width = my $height = 400;
my $offset_x = my $offset_y = 0;
my $id;

my $window = Gtk2::Window->new();
$window->set_size_request($height, $width);
$window->signal_connect('key-press-event', \&key_press_event_cb);
$window->signal_connect('destroy', sub { Gtk2->main_quit() });
my $image = Gtk2::Image->new();
my $src_pixbuf = Gtk2::Gdk::Pixbuf->new_from_file('testbild.tiff');
my $pixbuf = Gtk2::Gdk::Pixbuf->new($src_pixbuf->get_colorspace(), $src_pixbuf->get_has_alpha(), 
                                                                        $src_pixbuf->get_bits_per_sample(), 
$height, $width);
my $scale = 1;
update_pixbuf($src_pixbuf, $pixbuf, $offset_x, $offset_y, $scale);

$id = $image->signal_connect('size-allocate', sub {
                $pixbuf = Gtk2::Gdk::Pixbuf-> new ( $src_pixbuf->get_colorspace(), 
                                                                                        
$src_pixbuf->get_has_alpha(), 
                                                                                        
$src_pixbuf->get_bits_per_sample(), 
                                                                                        
$_[0]->allocation->width, $_[0]->allocation->height);
                $src_pixbuf->composite( $pixbuf, 0, 0, $_[0]->allocation->width, $_[0]->allocation->height, 
                                                                $offset_x, $offset_y, $scale, $scale, 
'bilinear', 255);

                $image->signal_handler_block($id);
                $image->set_from_pixbuf($pixbuf);
                $image->signal_handler_unblock($id);
});

$window->add($image);
$window->show_all();
Gtk2->main();

sub update_pixbuf {
        my ($src, $dest, $offset_x, $offset_y, $scale) = @_;
        $src->composite($dest, 0, 0, $image->allocation->width, $image->allocation->height, 
                                        $offset_x, $offset_y, $scale, $scale,   'bilinear',     255     );
        $image->set_from_pixbuf($dest);
}

sub key_press_event_cb {
        my ($window, $event) = @_;

        if      ($event->keyval() == $Gtk2::Gdk::Keysyms{plus})         { zoom( 1.2 ); }
        if      ($event->keyval() == $Gtk2::Gdk::Keysyms{minus})        { zoom( 0.8 ); }
        if      ($event->keyval() == $Gtk2::Gdk::Keysyms{Left})         { move( 30, 0, 1 ); }
        if      ($event->keyval() == $Gtk2::Gdk::Keysyms{Right})        { move(-30, 0, 1 );     } 
        if      ($event->keyval() == $Gtk2::Gdk::Keysyms{Up})           { move( 0, 30, 1 );     } 
        if      ($event->keyval() == $Gtk2::Gdk::Keysyms{Down})         { move( 0,-30, 1 );     }
        if      ($event->keyval() == $Gtk2::Gdk::Keysyms{q}) {          Gtk2->main_quit();
        } else {return 1;}
        update_pixbuf($src_pixbuf, $pixbuf, $offset_x, $offset_y, $scale);
}

sub zoom {
        my $factor = pop;
        $scale *= $factor;
        update_pixbuf($src_pixbuf, $pixbuf, $offset_x, $offset_y, $scale);
}

sub move {
        my ($x,$y,$rel) = @_;
        $offset_x *= $rel;
        $offset_y *= $rel;
        $offset_x += $x if ($offset_x+$x <= 0);
        $offset_y += $y if ($offset_y+$y <= 0);
        print ("X: $offset_x Y: $offset_y\n");
        print ("Alloc.: ",$image->allocation->width(),"\n");
        update_pixbuf($src_pixbuf, $pixbuf, $offset_x, $offset_y, $scale);
}



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