Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

saving a Gtk2 canvas which is bigger than the window

by zentara (Archbishop)
on Nov 05, 2006 at 15:48 UTC ( [id://582317]=CUFP: print w/replies, xml ) Need Help??

In Perl/Tk there is the postscript method for saving an entire unseen canvas. In Gtk2's Gnome2::Canvas, you can only grab a snapshot of the visible portion of the canvas. This is a way to slide thru a scrolled window( which contains a canvas), and stitch together a full snapshot.

It may seem clumsy the way I cycle thru the scrolled window, (and someone may be able to refine the loop), but this way makes it obvious what is happeneing.

Any comments, bugs found, improvements are welcome. ( I'm probably overlooking something :-) )

#!/usr/bin/perl use warnings; use strict; use Glib qw/TRUE FALSE/; use Gtk2 -init; use Gnome2::Canvas; my $debug = 0; # set to 1 to get small pixbuf files # Create the window my $window = new Gtk2::Window ( "toplevel" ); $window->signal_connect ("delete_event", sub { Gtk2->main_quit; }); $window->set_border_width (10); #$window->set_size_request(640,480); $window->set_position('center'); my $vbox = Gtk2::VBox->new( 0, 0 ); $window->add($vbox); $vbox->set_border_width(2); my $hbox = Gtk2::HBox->new( 0, 0 ); $vbox->pack_start($hbox,1,1,0); $hbox->set_size_request(320,240); $hbox->set_border_width(0); my $hbox1 = Gtk2::HBox->new( 0, 0 ); $vbox->pack_start($hbox1,0,0,0); $hbox1->set_border_width(0); my $scwin = Gtk2::ScrolledWindow->new(); my $ha1 = $scwin->get_hadjustment; my $va1 = $scwin->get_vadjustment; $scwin->set_policy('automatic','automatic'); $hbox->add($scwin); my $white = Gtk2::Gdk::Color->new (0xFFFF,0xFFFF,0xFFFF); my $canvas = Gnome2::Canvas->new(); $canvas->set_scroll_region(0,0,1000,1000); $canvas->modify_bg('normal',$white); $canvas->set_center_scroll_region (0); my $root = $canvas->root(); my $item = Gnome2::Canvas::Item->new($root, "Gnome2::Canvas::Ellipse", x1 => 0, y1 => 0, x2 => 1000, y2 => 400, fill_color=>"red", outline_color=>"black" ); $item = Gnome2::Canvas::Item->new($root, "Gnome2::Canvas::Ellipse", x1 => 0, y1 => 400, x2 => 1000, y2 => 800, fill_color=>"blue", outline_color=>"black" ); $item = Gnome2::Canvas::Item->new($root, "Gnome2::Canvas::Ellipse", x1 => 0, y1 => 800, x2 => 1000, y2 => 1000, fill_color=>"green", outline_color=>"black" ); $scwin->add($canvas); my $button2 = Gtk2::Button->new('Quit'); $hbox1->pack_start( $button2, FALSE, FALSE, 2); $button2->signal_connect( clicked => sub{ exit; }); my $button3 = Gtk2::Button->new('Save'); $hbox1->pack_start( $button3, FALSE, FALSE, 2); $button3->signal_connect( clicked => \&save_it,$canvas); $window->show_all; Gtk2->main; ####################################################### sub save_it{ my (undef, $widget) = @_; my ($width, $height) = $widget->get_size; my ($x,$y,$width1, $height1,$depth) = $widget->window->get_geometry; print "$width $height\n" if $debug; print "$width1 $height1\n" if $debug; # a hack to slide the viewport and grab each viewable area my $cols = int($width/$width1); my $cmod = $width % $width1; my $rows = int($height/$height1); my $rmod = $height % $height1; print "rows - rmod-> $rows - $rmod\n" if $debug; print "cols - cmod-> $cols - $cmod\n" if $debug; # create large blank pixbuf to hold the stitched image my $gdkpixbuf_l = Gtk2::Gdk::Pixbuf->new ('rgb', 0, 8, $width, $height); # get full rows and cols ################################## for my $c (0 .. $cols - 1 ){ #slide viewport along $ha1->set_value( $c * $width1 ); for my $r (0..$rows - 1 ){ $va1->set_value( $r * $height1 ); # create blank pixbuf to hold the small image my $gdkpixbuf = Gtk2::Gdk::Pixbuf->new ('rgb', 0, 8,$width1, $height1); $gdkpixbuf->get_from_drawable ($canvas->window, undef, 0, 0, 0, 0, $width1, $height1); # $src_pixbuf->copy_area ($src_x, $src_y, $width, $height, # $dest_pixbuf, $dest_x, $dest_y) $gdkpixbuf->copy_area (0, 0, $width1, $height1, $gdkpixbuf_l, $c*$width1, $r*$height1); $gdkpixbuf->save ("$0-$c-$r.jpg", 'jpeg', quality => 100) if $debug; } #end rows } #end cols ###################################################################### +## # get bottom odd row except lower right corner####################### for my $c (0 .. $cols - 1 ){ $ha1->set_value( $c * $width1 ); $va1->set_value( $rows * $height1 ); my $gdkpixbuf = Gtk2::Gdk::Pixbuf->new ('rgb', 0,8,$width1,$rmod); $gdkpixbuf->get_from_drawable ($canvas->window, undef, 0, 0, 0, 0, $width1, $rmod); $gdkpixbuf->copy_area (0, 0, $width1, $rmod, $gdkpixbuf_l, $c*$width1, $rows*$height1); $gdkpixbuf->save ("$0-$c-rmod.jpg", 'jpeg', quality => 100) if $debug; } #end odd row ###################################################################### +## # get right odd col except lower right corner ######################## +## for my $r (0 .. $rows - 1 ){ $ha1->set_value( $cols * $width1 ); $va1->set_value( $r * $height1 ); # create blank pixbuf to hold the image my $gdkpixbuf = Gtk2::Gdk::Pixbuf->new ('rgb', 0,8,$cmod, $height1); $gdkpixbuf->get_from_drawable ($canvas->window, undef, 0, 0, 0, 0, $cmod, $height1); $gdkpixbuf->copy_area (0, 0, $cmod, $height1, $gdkpixbuf_l, $cols*$width1, $r*$height1); $gdkpixbuf->save ("$0-$r-cmod.jpg", 'jpeg', quality => 100) if $debug; } #end odd col ###################################################################### +## # get lower right corner ########################## $ha1->set_value( $cols * $width1 ); $va1->set_value( $rows * $height1 ); # create blank pixbuf to hold the image my $gdkpixbuf = Gtk2::Gdk::Pixbuf->new ('rgb', 0,8,$cmod,$rmod); $gdkpixbuf->get_from_drawable ($canvas->window, undef, 0, 0, 0, 0, $cmod, $rmod); $gdkpixbuf->copy_area (0, 0, $cmod, $rmod, $gdkpixbuf_l, $width - $cmod, $height - $rmod); $gdkpixbuf->save ("$0-rmod-cmod.jpg", 'jpeg', quality => 100) if $debug; ###################################################################### +## $gdkpixbuf_l->save ("$0-large.jpg", 'jpeg', quality => 100); $ha1->set_value( 0 ); $va1->set_value( 0 ); return FALSE; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://582317]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2024-03-19 09:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found