Gossamer Forum
Home : Products : DBMan : Customization :

Automatic Thumbnails

(Page 2 of 3)
> > > >
Quote Reply
Re: Automatic Thumbnails In reply to
Hi Mark,

Sorry I haven't used the multiple file upload mod... best to ask Carol Wink. As for the batch convert thing, try this: cristy@imagemagick.org I found Cristy very useful, she answered all my questions!



Cheers!
Ben
------------
http://www.travel-experiences.com
Quote Reply
Re: Automatic Thumbnails In reply to
Probably. I don't know how to use ImageMagick, so I really can't tell you for sure, though.

JPD
http://www.jpdeni.com/dbman/
Quote Reply
Re: Automatic Thumbnails In reply to
Well, that e-mail addy you gave me was bouncing my mail, but I've come up with something that just might work. But I still really need:

1) To implement the original auto-thumbnail code with the new multi file-upload mod.
2) A converter script that will move my old images into the directory/images (multi file-upload) format, and which would run the batch thumbnail script below on each of the directories. Breaking this down step by step, it would:

a. read the file name minus the JPG or GIF extension (leaving the ID#)
b. create a directory with the ID# as the dir name
c. move that file into that directory, and move onto the next file
d. for each of the directories, run the script below

I hope you understand this - I confused myself the first time I wrote it! Smile Thanks!

----------------------------------------------
Below is an attempt at a script that will batch thumbnail images. It has not been tested yet!!!!

#!/usr/local/bin/perl
my $tnsize=90; # size of thumbnails
my $tnquality=70; # quality of thumbnails

my @pics = (<*.jpg>,<*.JPG>,<*.gif>,<*.GIF>);

# create a directory for the thumbnails
system ("mkdir tn") if (!-d "tn");

my $counter=0;

foreach $_ (sort @pics) {
print $_;
system ("convert -geometry ".$tnsize."x".$tnsize.
" -quality $tnquality $_ tn/$_") == 0
|| die "Problems with convert: $?\n";
print " ... done\n";
}

Quote Reply
Re: Automatic Thumbnails In reply to
Okay. I'll give it a try. But the actual thumbnail stuff is up to you. Smile

It would be a good idea to create a new directory for your "big" graphic files and not use the current save directory for them. I think it will be easier that way. Then when you're all done you can delete the old files and directory.

The code below will read the files from the old directory and create a sub_directory in the new directory. Also, there will be a variable $name that you can use for your thumbnails and such. The full filename is in the variable $file.

Code:

$old_directory = '/path/to/old/directory';
$new_directory = '/path/to/new/directory';

opendir (OLD, $old_directory) or die("unable to open old directory. Reason: $!");
@files = readdir(GRAPHIC);
closedir (OLD);

foreach $file (@files) {
if (($file =~ /(.+)\.jpg$/i) or ($file =~ /(.+)\.gif$/i)) {
$name = $1;
$dirsuccess = mkdir "$new_directory/$name", 0777;
put your other code in here for copying the file to the new directory
and creating your thumbnails

}
}

JPD
http://www.jpdeni.com/dbman/
Quote Reply
Re: Automatic Thumbnails In reply to
Hi JPD,

Thanks for the script, but something's not working right. I just took out the "put your other code..." text, and added #!/usr/local/bin/perl, but the script doesn't create the subdirectories or return an error message. I have created a /home/myserver/www/testpics directory and CHMODed that 777, and doublechecked my paths. Any ideas? Thanks.

Quote Reply
Re: Automatic Thumbnails In reply to
I changed the name of the filehandle, but didn't change it every place.

@files = readdir(GRAPHIC);

should be

@files = readdir(OLD);

JPD
http://www.jpdeni.com/dbman/
Quote Reply
Re: Automatic Thumbnails In reply to
Hi JPD,

YAY! I have the script working, complete with the copy command and thumbnail! Now, I just need to implement the:

$ALLOWED_EXT =~ s/\\.//g;
$ALLOWED_EXT =~ s/\$//g;
@extensions = split (/\Q|\E/o,$ALLOWED_EXT);
GRAPHIC: foreach $extension (@extensions) {
if (-e "$SAVE_DIRECTORY/$in{$db_key}.$extension") {
$filename="$in{$db_key}.$extension";
last GRAPHIC;
}
}
require "thumbnail.cgi"; #Calls file
&thumbnail($filename); #Executes file for uploaded pic

code into the html_add_success and html_modify_success subs I think (for the new multi-file upload MOD). Do you see any glaring error that would prevent this from working or what else I have to do? I'll go do some more testing now. I think I will need to also pass the db_key to the thumbnail.cgi script. For those of you interested, here's the CONVERTER SCRIPT I've made and tested sucessfully. Basically, this will just take the files you had for a previous file-upload mod, and put them into the multi-upload mod format. It also makes a thumbnail of the original picture, and puts it in a tn subdirectory. Use it at your own risk and modify it as needed.

#!/usr/local/bin/perl
$old_directory = '/home/myserver/www/testbig';
$new_directory = '/home/myserver/www/testpics';
$CONVERT = "/usr/X11R6/bin/convert";
$THUMBNAIL_SIZE_W = 90; #pixel width of thumbnail
$THUMBNAIL_SIZE_H = 90; #pixel height of thumbnail
opendir (OLD, $old_directory) or die("unable to open old directory. Reason: $!");
@files = readdir(OLD);
closedir (OLD);
foreach $file (@files) {
if (($file =~ /(.+)\.jpg$/i) or ($file =~ /(.+)\.gif$/i)) {
$name = $1;
$dirsuccess = mkdir "$new_directory/$name", 0777;
system "cp $old_directory/$file $new_directory/$name/$file";
mkdir "$new_directory/$name/tn", 0777;
$CONVERT="$CONVERT -geometry ${THUMBNAIL_SIZE_W}x${THUMBNAIL_SIZE_H} -quality 70";
system "$CONVERT $old_directory/$file $new_directory/$name/tn/$file"; }
}

Quote Reply
Re: Automatic Thumbnails In reply to
JPD,

All I believe I need is a script to call up the thumbnail.cgi, just like the the one Ben posted in the first post of this thread, only it also passes the db_key. I need to know which subroutine(s) the code has to go, and what I need to change in it. My thumbnail.cgi script is below, and of course I need to change the (dbkey) to whatever gets passed in. Thanks a million!

sub thumbnail {
$CONVERT = "/usr/X11R6/bin/convert";
$THUMBNAIL_SIZE_W = 130; #pixel width of thumbnail
$THUMBNAIL_SIZE_H = 130; #pixel height of thumbnail
$SAVE_DIRECTORY_PATH = "/home/myserver/www/testpics/(dbkey)";
my ($filename) = $_[0];
mkdir "$SAVE_DIRECTORY_PATH/tn", 0777;
$CONVERT="$CONVERT -geometry ${THUMBNAIL_SIZE_W}x${THUMBNAIL_SIZE_H} -quality 75";
system "$CONVERT $SAVE_DIRECTORY_PATH/$filename $SAVE_DIRECTORY_PATH/tn/$filename";
}
1;

Quote Reply
Re: Automatic Thumbnails In reply to
Seems to me like the best place to put it would be in sub validate_upload, right after you save the file. Wouldn't that seem logical to you?

I'm not sure of your directory structure here. Is it

Code:
<SAVE_DIRECTORY>
<Key value directory>
file names
<tn>
tn_file names
JPD
http://www.jpdeni.com/dbman/
Quote Reply
Re: Automatic Thumbnails In reply to
Yes, that is the structure (except that I've kept the tn filenames the same as the original file - without the tn_).

So I think the only thing we need to do to Ben's code (below):

$ALLOWED_EXT =~ s/\\.//g;
$ALLOWED_EXT =~ s/\$//g;
@extensions = split (/\Q|\E/o,$ALLOWED_EXT);
GRAPHIC: foreach $extension (@extensions) {
if (-e "$SAVE_DIRECTORY/$in{$db_key}.$extension") {
$filename="$in{$db_key}.$extension";
last GRAPHIC;
}
}
require "thumbnail.cgi"; #Calls file
&thumbnail($filename); #Executes file for uploaded pic

is also pass the db_key so I can reference it in the path for ImageMagick. If I just knew how to pass this, and if this works foreach file like I think it should, everything will be working. I hope you understand what I'm trying to do here. Actually, do we even have to have a thumbnail.cgi file, or can we just put all the code within db.cgi? And yes, sub validate_upload...I must have skipped right over it - I think I was expecting to see it in html.pl or something. Thanks, Carol...I really appreciate it!

Quote Reply
Re: Automatic Thumbnails In reply to
Hi JPD,

Well, I thought I was on to something when I wrote the code below. The db.cgi doesn't give any errors, but the tn directory and thumbnail still aren't being created. My code is added on to the very end, and the rest of the sub is like the original. Maybe I just have the code in the wrong spot? Thanks.

sub validate_upload {
# --------------------------------------------------------
my ($filekey,$filename,$extlength,$filehandle,$totalbytes,$buffer,$bytes,@extensions,@ext,
$newdirname,$dirsuccess,$num_files,$prev_files,$prev_bytes);

$| = 1;

if (!(-e $SAVE_DIRECTORY)) {
return "The directory doesn't exist. Make sure that this directory is a complete path name,<BR>
not a URL or something similar. It should look similar to<BR>
/home/username/public_html/uploads";
}
if (!(-W $SAVE_DIRECTORY)) {
return "The directory isn't writable. Make sure that this directory is writable by all users.<BR>
At your UNIX command prompt, type chmod 777 $SAVE_DIRECTORY";
}
if (!(-d $SAVE_DIRECTORY)) {
return "The directory you specified isn't really a directory.<BR>
Make sure that this is indeed a directory and not a file.";
}
$newdirname = $in{$db_key};
if (!(-e $SAVE_DIRECTORY/$newdirname)) {
$dirsuccess = mkdir "$SAVE_DIRECTORY/$newdirname", 0777;
}
else {
opendir (GRAPHIC, $SAVE_DIRECTORY/$newdirname) or &cgierr("unable to open directory. Reason: $!");
@files = readdir(GRAPHIC);
closedir (GRAPHIC);
foreach $file (@files) {
next if ($file =~ /^\./); # Skip "." and ".." entries..
next if ($file =~ /^index/); # Skip index.htm type files..
++$prev_files;
@stats = stat "$SAVE_DIRECTORY/$newdirname/$file";
$prev_bytes +=$stats[7];

# here's my code
$CONVERT = "/usr/X11R6/bin/convert";
$THUMBNAIL_SIZE_W = 90; #pixel width of thumbnail
$THUMBNAIL_SIZE_H = 90; #pixel height of thumbnail
mkdir "$SAVE_DIRECTORY/$newdirname/tn", 0777;
$CONVERT="$CONVERT -geometry ${THUMBNAIL_SIZE_W}x${THUMBNAIL_SIZE_H} -quality 70";
system "$CONVERT $SAVE_DIRECTORY/$newdirname/$file $SAVE_DIRECTORY/$newdirname/tn/$file";
}
}
# the rest of the sub is the same as the original

Quote Reply
Re: Automatic Thumbnails In reply to
This is the wrong place. At this point, the file has not yet been uploaded.

I would try it after

chmod (0666, "$SAVE_DIRECTORY\/$newdirname\/$filename");

and use $filename as the name of your file.

JPD
http://www.jpdeni.com/dbman/
Quote Reply
Re: Automatic Thumbnails In reply to
JPD-

Good news...it works great! Now if you can give help me out with 2 final things....they should be easy (cut & paste stuff). I need to 1) delete the thumbnail when the user deletes a big picture or the record. Remember, the thumbnail is the same filename, but just in the "tn" subdirectory of the the IDs subdirectory, so we probably just need to copy/modify part of sub delete_records. 2) I need to change the print graphics code (below) just to show one thumbnail instead of all.

if (-e "$SAVE_DIRECTORY/$rec{$db_key}/tn") {
opendir (GRAPHIC, "$SAVE_DIRECTORY/$rec{$db_key}/tn") or &cgierr("unable to open directory: $SAVE_DIRECTORY/$rec{$db_key}. Reason: $!");
@files = readdir(GRAPHIC);
closedir (GRAPHIC);
foreach $file (@files) {
next if ($file =~ /^\./); # Skip "." and ".." entries..
next if ($file =~ /^index/); # Skip index.htm type files..
print qq|<img src= "$SAVE_DIRECTORY_URL/$rec{$db_key}/tn/$file">|;
}
}

Thanks for your patience with me and these mods...I really appreciate all your time and help!

Quote Reply
Re: Automatic Thumbnails In reply to
To delete the thumbnail at the time one picture is deleted, in sub modify_record, make the following change:

Code:

foreach $key (keys %in) {
if ($in{$key} eq 'delete') {
unlink "$SAVE_DIRECTORY/$in{$db_key}/$key";
unlink "$SAVE_DIRECTORY/$in{$db_key}/tn/$key";
}
}
To delete all the thumbnails when a record is deleted

Code:

opendir (GRAPHIC, "$SAVE_DIRECTORY/$data[$db_key_pos]") or &cgierr("unable to open directory in delete records: $SAVE_DIRECTORY/$data[$db_key_pos]. Reason: $!");
@files = readdir(GRAPHIC);
closedir (GRAPHIC);
foreach $file (@files) {
unlink ("$SAVE_DIRECTORY/$data[$db_key_pos]/$file");
}
opendir (GRAPHIC, "$SAVE_DIRECTORY/tn/$data[$db_key_pos]") or &cgierr("unable to open directory in delete records: $SAVE_DIRECTORY/tn/$data[$db_key_pos]. Reason: $!");
@files = readdir(GRAPHIC);
closedir (GRAPHIC);
foreach $file (@files) {
unlink ("$SAVE_DIRECTORY/tn/$data[$db_key_pos]/$file");
}
rmdir "$SAVE_DIRECTORY/tn/$data[$db_key_pos]";

rmdir "$SAVE_DIRECTORY/$data[$db_key_pos]";
}
In Reply To:
2) I need to change the print graphics code (below) just to show one thumbnail instead of all.
How will you know which one to print?

JPD
http://www.jpdeni.com/dbman/
Quote Reply
Re: Automatic Thumbnails In reply to
>>How will you know which one to print?<<

I just want the first file to be printed...if that's possible...or whatever graphic file the script encounters first. Thanks Carol!

Quote Reply
Re: Automatic Thumbnails In reply to
Well, let's see.

Code:

if (-e "$SAVE_DIRECTORY/$rec{$db_key}/tn") {
opendir (GRAPHIC, "$SAVE_DIRECTORY/$rec{$db_key}/tn") or &cgierr("unable to open directory: $SAVE_DIRECTORY/$rec{$db_key}. Reason: $!");
@files = readdir(GRAPHIC);
closedir (GRAPHIC);
foreach $file (@files) {
next if ($file =~ /^\./); # Skip "." and ".." entries..
next if ($file =~ /^index/); # Skip index.htm type files..
print qq|<img src= "$SAVE_DIRECTORY_URL/$rec{$db_key}/tn/$file">|;
last;
}
}
Not sure that will work, but it might. Smile

JPD
http://www.jpdeni.com/dbman/
Quote Reply
Re: Automatic Thumbnails In reply to
Yay, it worked! I think everything I need with this sub-mod is done, so hopefully you'll stop seeing the word thumbnail for a good while Smile. Thank you for all your help!

Quote Reply
Re: Automatic Thumbnails In reply to
Hi JPD,

I've found one tiny glitch in the multi-upload/thumbnail creation system: If a user uploads 5 files and only 2 or so are allowed because the total file size is too big, the thumbnails are still created while the big pictures are not accepted. Any ideas? Thanks.

BTW, i'm using the code you posted a few posts up.

Quote Reply
Re: Automatic Thumbnails In reply to
You could put code just before return "ok"; that would read the directory, check to see if there was a matching thumbnail file and, if there wasn't, create the thumbnail then.

JPD
http://www.jpdeni.com/dbman/
Quote Reply
Re: Automatic Thumbnails In reply to
I think I confused you a little - for some reason, even if a big picture isn't saved (maybe because the total size has been exceeded), the script still creates a thumbnail for it. I have the logic for what I think should happen, but I'm not sure exactly how to write it and where to place it.

-reads each file in the "thumbnail" directory
-if there is a matching "big picture" (remember, the filenames are the exact same, only in another directory) for each thumbnail, then it leaves it alone
-else it deletes the thumbnail file

Thanks JPD, I hope you can figure it out Smile

Quote Reply
Re: Automatic Thumbnails In reply to
You could do it that way, too. I was thinking to put it just before return "ok"; so that it wouldn't write the file at all if the file was rejected. Six o' one.... Smile

I think it would work if you added the following right after the thumnail is written:

push(@Files_Written, "$SAVE_DIRECTORY\/$newdirname\/tn\/$filename");

The script uses this array to delete rejected files, so it would delete the thumbnail files as well as the "big" files.

JPD
http://www.jpdeni.com/dbman/
Quote Reply
Re: Automatic Thumbnails In reply to
Hmm, I don't think that worked. I've tried directly before the return "ok", and also after the thumbnail script. I've copied half of the sub in db.cgi so maybe you could see where exactly it goes. Thanks.

foreach $key (sort {$a <=> $b} $query->param()) {
next if ($key =~ /^\s*$/);
next if ($query->param($key) =~ /^\s*$/);
next if ($key !~ /^file-to-upload-(\d+)$/);
$Number = $1;
++$num_files;
if ($query->param($key) =~ /([^\/\\]+)$/) {
$filename = $1;
$File_Handle = $query->param($key);
unless ($filename =~ /$ALLOWED_EXT/) {
$ALLOWED_EXT =~ s/\\//g;
$ALLOWED_EXT =~ s/\$//g;
@ext = split (/\Q|\E/o,$ALLOWED_EXT);
$ALLOWED_EXT = join(" or ",@ext);
return "Only files with the following extension(s) are allowed: $ALLOWED_EXT";
}
}
else {
return "You attempted to upload <B>$filekey</B> that isn't properly formatted. Please rename the file
on your computer, and attempt to upload it again. Files may not have forward or backward slashes in
their names. Also, they may not be prefixed with one (or more) periods.";
}

if (!open(OUTFILE, ">$SAVE_DIRECTORY\/$newdirname\/$filename")) {
return "There was an error opening '$SAVE_DIRECTORY\/$newdirname\/$filename' for Writing.\n";
}

binmode(OUTFILE); # This is needed to work on Windows/NT platforms.

undef $BytesRead;
undef $Buffer;

while ($bytes = read($File_Handle,$buffer,1024)) {
$totalbytes += $bytes;
print OUTFILE $buffer;
}

push(@Files_Written, "$SAVE_DIRECTORY\/$newdirname\/$filename");

close($File_Handle);
close(OUTFILE);

chmod (0666, "$SAVE_DIRECTORY\/$newdirname\/$filename");
$CONVERT = "/usr/X11R6/bin/convert"; #next 6 lines make thumbnail
$THUMBNAIL_SIZE_W = 90; #pixel width of thumbnail
$THUMBNAIL_SIZE_H = 90; #pixel height of thumbnail
mkdir "$SAVE_DIRECTORY/$newdirname/tn", 0777;
$CONVERT="$CONVERT -geometry ${THUMBNAIL_SIZE_W}x${THUMBNAIL_SIZE_H} -quality 70";
system "$CONVERT $SAVE_DIRECTORY/$newdirname/$filename $SAVE_DIRECTORY/$newdirname/tn/$filename";
}

if (($totalbytes + $prev_bytes) > $MAXIMUM_UPLOAD && $MAXIMUM_UPLOAD > 0) {
foreach $written (@Files_Written) {
unlink "$written";
}
return "You have exceeded your upload limit for this record.<BR>
Your files contain <B>$totalbytes</B> bytes.<BR>
Combined with previous uploads totaling <B>$prev_bytes</B>, this
exceeds the maximum limit of <B>$MAXIMUM_UPLOAD</B> bytes per record.<BR>
Your files were not saved.<BR>
Please try again.";
}
if (($num_files + $prev_files) > $MAXIMUM_FILES) {
foreach $written (@Files_Written) {
unlink "$written";
}
return "You have exceeded your upload limit for this record.<BR>
You uploaded <B>$num_files</B> files.<BR>
Combined with previous <B>$prev_files</B> uploads, this
exceeds the maximum limit of <B>$MAXIMUM_FILES</B> files per record.<BR>
Your files were not saved.<BR>
Please try again.";
}
return "ok";
}


Quote Reply
Re: Automatic Thumbnails In reply to
Hi JPD,

Can you please take a look at my previous message? I hope you feel better! Smile Thanks.

Quote Reply
Re: Automatic Thumbnails In reply to
Code:
opendir (GRAPHIC, "$SAVE_DIRECTORY/$newdirname") or &cgierr("unable to open directory: $SAVE_DIRECTORY/$newdirname. Reason: $!");
@bigfiles = readdir(GRAPHIC);
closedir (GRAPHIC);
foreach $file (@bigfiles) {
$big_file{$file} = 1;
}
opendir (GRAPHIC, "$SAVE_DIRECTORY/$newdirname/tn") or &cgierr("unable to open directory: $SAVE_DIRECTORY/$newdirname/tn. Reason: $!");
@smfiles = readdir(GRAPHIC);
closedir (GRAPHIC);
foreach $file (@smfiles) {
unless ($big_file{$file}) {
unlink "$SAVE_DIRECTORY/$newdirname/tn/$file";
}
}
JPD
http://www.jpdeni.com/dbman/
Quote Reply
Re: Automatic Thumbnails In reply to
Hi, Ben

After all the discussion, has your mod been tested sucessfully. What's the final version? I am eager to install it.

Thanks.

Long

> > > >