Code Comments
Programming Forum and web based access to our favorite programming groups.Created a Scrolled Zinc widget. Originally was using a Canvas, but Zinc offers somethings that Canvas can't touch. I have a Zinc that is setup to load an image, and then with zoom in/out buttons you can adjust your view of the image. The way I was zooming with a canvas involved zooming the image, then subsampling. So I originally ported that over to Zinc and it worked fine. However, zooming this way won't proportion anything else. So I started messing with Zinc's scale. Seemed to work fine at first, until I attempted to scroll. Trying to scroll on a scaled image is incredibly slow compared to a smooth scroll provided by the zoom/resample method. Tried on Linux and Windows, no difference in effect. Below is a test case that shows the difference in speeds. Just place a jpeg image in the same directory. Size should not be much of a concern; I used files ranging from 50K to 500K with no visible change. Any ideas? # Zinc Slug #!/usr/bin/perl use Tk; use Tk::JPEG; use Tk::Zinc; use MIME::Base64; $mw = MainWindow->new(); $mw->idletasks; $jscreen = $mw->screenwidth; $kscreen = $mw->screenheight - 50; $mw->geometry("$jscreen" . "x" . "$kscreen" . "+0+0"); # Only tested with jpeg. open(PIC, "image.jpg") or die print "Need a jpeg named image.jpg to make this little demo work...\n"; binmode(PIC); $buffer = ''; while(<PIC> ) { $buffer .= $_; } close(PIC); $image = encode_base64($buffer); $zinc = $mw->Scrolled('Zinc', -scrollbars => 'osoe', -borderwidth => 0)->pack(-side => 'left', -fill => 'both', -expand => 1); $zoomframe = $mw->Frame()->pack(-side => 'left', -fill => 'y'); $label1 = $zoomframe->Label(-text => 'Zoom')->pack(-side => 'top', -pady => 5); $button1 = $zoomframe->Button(-text => '+', -command => [\&zoom,1])->pack(-side => 'top', -pady => 5, -fill => 'x'); $button2 = $zoomframe->Button(-text => '-', -command => [\&zoom,0])->pack(-side => 'top', -pady => 5, -fill => 'x'); $radio1 = $zoomframe->Radiobutton(-text => 'Resize', -variable => \$scale, -value => 0, -command => \&reset)->pack(-side => 'top', -pady => 5, -fill => 'x'); $radio2 = $zoomframe->Radiobutton(-text => 'Scale', -variable => \$scale, -value => 1, -command => \&reset)->pack(-side => 'top', -pady => 5, -fill => 'x'); $label2 = $zoomframe->Label(-textvariable => \$percent)->pack(-side => 'top', -pady => 5); $scale = 0; $factor1 = 4; $factor2 = 4; $photo = $zinc->Photo(-data => $image, -format => 'jpeg'); $percent = '100%'; $group = $zinc->add('group', 1); $realimage = $zinc->add('icon', $group, -position => [0,0], -image => $photo, -tags => 'image'); $zinc->configure(-scrollregion => [$zinc->bbox('image')]); MainLoop; sub reset { $factor1 = 4; $factor2 = 4; $percent = '100%'; $zinc->remove('image'); $zinc->xview('moveto', 0); $zinc->yview('moveto', 0); $zinc->remove('group', 1); $group = $zinc->add('group', 1); $realimage = $zinc->add('icon', $group, -position => [0,0], -image => $photo, -tags => 'image'); $zinc->configure(-scrollregion => [$zinc->bbox('image')]); } sub zoom { my ($zoomer) = @_; if($zoomer == 0 && $factor1 == 1) { return; } $mw->Busy; if($scale == 0) { if($realimage) { $zinc->remove('image'); undef($realimage); } if($zoomimage) { $zoomimage->delete; undef($zoomimage); } if($subbedimage) { $subbedimage->delete; undef($subbedimage); } $zoomimage = $zinc->Photo; $subbedimage = $zinc->Photo; $zoomimage->blank; $subbedimage->blank; if($zoomer == 1) { $factor1++; } else { $factor1--; } $zoomimage->copy($photo, -zoom => $factor1); $subbedimage->copy($zoomimage, -subsample => $factor2); $zinc->xview('moveto', 0); $zinc->yview('moveto', 0); $realimage = $zinc->add('icon', $group, -position => [0,0], -image => $subbedimage, -tags => 'image'); $zinc->configure(-scrollregion => [$zinc->bbox('image')]); } else { if($zoomer == 1) { $factor1++; } else { $factor1--; } my $newscale = $factor1/$factor2; $zinc->xview('moveto', 0); $zinc->yview('moveto', 0); $zinc->scale($group, $newscale,$newscale); $zinc->configure(-scrollregion => [$zinc->bbox('image')]); } $mw->Unbusy; $mw->update; $percent = (($factor1/$factor2) * 100) . '%'; } # Zinc Slug
Post Follow-up to this messageOn 30 Mar 2005 12:57:31 -0800, "T.J." <tjtoo@phreaker.net> wrote: >Created a Scrolled Zinc widget. Originally was using a Canvas, but Zinc >offers some
things that Canvas can't touch. I have a Zinc that is >setup to load an image, and then with zoom in/out buttons you can >adjust your view of the image. The way I was zooming with a canvas >involved zooming the image, then subsampling. So I originally ported >that over to Zinc and it worked fine. However, zooming this way won't >proportion anything else. So I started messing with Zinc's scale. >Seemed to work fine at first, until I attempted to scroll. Trying to >scroll on a scaled image is incredibly slow compared to a smooth scroll >provided by the zoom/resample method. Tried on Linux and Windows, no >difference in effect. Below is a test case that shows the difference in >speeds. Just place a jpeg image in the same directory. Size should not >be much of a concern; I used files ranging from 50K to 500K with no >visible change. Any ideas? Your script seems to work fine for smaller images for me. You just have to accept the limits of Tk, when it comes to image manipulation. It must be doing alot of internal computations when you try to scroll the expanded image. You probably would have to write something in Inline::C or XS to do what you want faster. Here is an idea. There is a fantastic image viewer, written in GTK2, and has a perl module for it. It is at http://imagic.weizmann.ac.il/~dov/f...tk-image-viewer Install it, and get the perl module for it. It has VERY FAST and SMOOTH scaling, zooming, and panning with mouse clicks and drags. It uses the powerful GTK2 c libraries for image manipulation. You can use it within a Tk script. It's
, you can combine Tk and Gtk2 into 1 script. You can use GTK2's equivalent of Tk's "DO ONE LOOP", to combine the event loops. Here is the imageviewer in a Tk script. (It would be great if someone knowledgable, could make a Tk XS interface to these c libs). #!/usr/bin/perl -w use strict; use Gtk2; use Gtk2::ImageViewer; use Tk; my $mw = tkinit; Gtk2->init; my $window = Gtk2::Window->new; my $file = shift || 'bridget-1.jpg'; my $imgv = new_from_file Gtk2::ImageViewer($file); $window->add($imgv); $window->show_all; my $tktimer = $mw->repeat(10, sub{ Gtk2->main_iteration while Gtk2->events_pending; }); $mw->Label(-text=>'Gtk2-ImageViewer')->pack(); $mw->Button(-text=>'Quit', -command => sub{exit} )->pack(); MainLoop; __END__ Just to show you how easy the imageviewer is in pure gtk2 ######################################## ############################## # Trivial use of GtkImageViewer. ######################################## ############################## use Gtk2; use Gtk2::ImageViewer; Gtk2->init; $window = Gtk2::Window->new(); $window->signal_connect('destroy', sub { Gtk2->main_quit }); $imgv = new_from_file Gtk2::ImageViewer(shift); $window->add($imgv); $window->show_all(); main Gtk2; __END__ -- I'm not really a human, but I play one on earth. http://zentara.net/japh.html
Post Follow-up to this messageInteresting. I believe Gtk2 does have win32 source so I will look into that, thank you. Just to clarify the point I was making was that using the photo method of cropping and subsampling was producing the same zoomed-in image that Zinc's scale was. However, the image scrolling was much slower with scale. This surprised me because I was under the impression that Zinc was a pretty efficient canvas-type implementation. Not to say that it isn't! =) I just thought it would be able to handle this operation at the same speed/better than the crop-subsample method. The speed that crop-subsampling produces is more than adequate for my purposes, but it would be really sweet if scale were just as fast (So I could then add text and have it get smaller/larger as the image does). > Your script seems to work fine for smaller images for me. You just have > to accept the limits of Tk, when it comes to image manipulation. It must > be doing alot of internal computations when you try to scroll the > expanded image. You probably would have to write something in > Inline::C or XS to do what you want faster.
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.