Hi again. Just to demonstrate the speed up from using Storable, I chopped down the script I mentioned above, so you can see the basics. Just run it in a directory with some jpgs in a subdir called "pics". The first run will be slow as the thumbnails are built, but exit the program and restart. The second run will be very fast by comparison.
#!/usr/bin/perl
use warnings;
use strict;
use Tk;
use Tk::Pane;
use Tk::JPEG;
use MIME::Base64;
use Imager;
use File::Basename;
use File::Path;
use File::Copy;
use Storable;
use POSIX qw(strftime);
use YAML;
my $photo;#my $photo;
my $image;
my %info;
my @exts = qw(.jpg .png .gif); # list allowed extensions
if(-e 'notebook.db'){
%info = %{retrieve('notebook.db')}; # direct to hash
}else{ make_thumbs() }
#to see a dump of the db, just put an 1 as an arg to the script
if(shift){print Dump(\%info);exit;}
my $mw = MainWindow->new(-bg=>'black');
$mw->geometry('800x700+100+15');
#setup auto save of storable db
$mw->protocol('WM_DELETE_WINDOW' => sub { &save_it() });
$SIG{__DIE__} = sub { &save_it()};
$SIG{INT} = sub { &save_it()};
$mw->bind('<Control-c>', [sub{&save_it(); Tk::exit;}] );
my $mainframe = $mw->Frame(-background=>'black')
->pack(-side => "right", -anchor => "n",
-fill=>'both', -expand=>1);
#fill mainframe with default screen
setup_pane();
MainLoop;
#############################################################
sub setup_pane{
my $pane = $mainframe->Scrolled('Pane', Name => 'Main Display',
-width => 1000,
-height =>1000,
-background => 'black',
-scrollbars => 'osoe',
-sticky => 'n',
)->pack(-side => "left", -anchor => "n",
-fill=>'both',-expand=>1);
foreach my $key ( keys %info ){
my $image = $mw->Photo(
-data => $info{$key}{'thumbnail'} );
$pane->Label(-image => $image,
-background =>'black'
)->pack(-side => 'top',
-anchor => 'n',
-fill => 'both',
-expand => 1,
);
}
}
################################################################
sub make_thumbs{
umask 0022;
my @pics = <pics/*.jpg pics/*.gif pic/*.png>;
my $image = Imager->new();
foreach my $pic (@pics){
my ($basename,$path,$suffix) = fileparse($pic,@exts);
$info{$basename}{'name'} = $basename;
$info{$basename}{'pic'} = "pics/$basename.jpg"; #convert to jp
+g
$image->open(file=>$pic) or die $image->errstr();
# Create smaller version
my $temp;
my $thumb = $image->scale(xpixels=>100);
print "Storing thumbnail: $basename.jpg\n";
$thumb->write(data => \$temp,
type =>'jpeg',
jpegquality=>30) or die $thumb->errstr;
$info{$basename}{'thumbnail'} = encode_base64($temp);
}
print "\n#################endofthumbcreation##########################
+#####\n";
}
###################################################################
sub save_it{
store(\%info,'notebook.db');
print "saved\n";
exit;
}
#####################################################################
I'm not really a human, but I play one on earth.
flash japh
| [reply] [d/l] |
Didn't know that base64 encoding images speeded up image loading. It's certainly a step in the right direction. Thanks, man (zentara).
Zenatara wrote:
"People have been trying to experiment with somehow "freezing" and "thawing" the actual Tk::Photo objects"
Yes, that would be the ideal solution. I assume that quite allot happens with that base64 encoded data before photo is generated, but since it's a c widget (Tk::Photo, child of Tk::Image) I didn't understand much of what is going on inside..
from image.pm
my $obj = $widget->Tk::image('create',$leaf,@_);
How/where can we decrypt (or even find) the "create" method?
| [reply] |
Didn't know that base64 encoding images speeded up image loading
Well you are misinterpreting what is happening. The base64encoding only is helping in an indirect way, and really is a Tk-only thing. Tk has a particular ideosyncrancy, that it wants it's images to be base64encoded (the reason is probably buried deep down in the c code). When you load a Photo object from -file, it does the base64encoding automatically. When loading a Photo object from -data, you must provide the encoding yourself. So, in this particular instance, we can save the thumbnails as encoded images in one big file. That gives us 2 speed bonuses. The first is that we are saving the time it takes for Tk to base64encode the files, and the second, is that the system only has to open 1 file, the 'notebook.db', instead of 100 smaller thumbnail files. Disk I/O is the biggest slowdown in most programs. As far as freezing the Photo object itself, you are in virgin territory. Many attempts have been made by people smarter than me, and they have given up because of all the complexities.
I'm not really a human, but I play one on earth.
flash japh
| [reply] |
Well, no matter what widget you use, if you try to load alot (like > 20) images, it is going to take time. How many are you trying to load at startup?The only thing I can think of, is to base64encode the images(and their thumbnails) and save them in a Storable hash db. Then at startup, all you need to do is import the base64 coded images into a Tk::Photo object using the -data option. That would save you remaking the thumbnails, and would speed up the read operations. People have been trying to experiment with somehow "freezing" and "thawing" the actual Tk::Photo objects, and importing them from the db. That would be the ideal. It would seem possible to do. For an example of Storable and Tk (not exactly your situation, but shows the principles) see ztkdb
I'm not really a human, but I play one on earth.
flash japh
| [reply] |