For Programmers: Free Programming Magazines  


Home > Archive > PerlTk > March 2005 > Tk::Zinc scale is running sluggish









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Tk::Zinc scale is running sluggish
T.J.

2005-03-30, 8:57 pm

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?


# 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

zentara

2005-03-31, 3:58 pm

On 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
T.J.

2005-03-31, 3:58 pm

Interesting. 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.


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com