diff options
Diffstat (limited to 'lib/images.pm')
| -rw-r--r-- | lib/images.pm | 509 |
1 files changed, 509 insertions, 0 deletions
diff --git a/lib/images.pm b/lib/images.pm new file mode 100644 index 0000000..1b69db7 --- /dev/null +++ b/lib/images.pm @@ -0,0 +1,509 @@ +####################################################################### +# thumbnailing + +sub is_ungainly + { + my $fn = shift; return $fn =~ /tif$/ || $fn =~ /bmp/; + } +sub thumbnail_filename + { + my ($filename) = @_; + if (is_ungainly($filename)) + { + $filename =~ s/\..*$/.jpg/; + } + return lc $filename; + } +sub make_image_thumb + { + my ($args) = @_; + + my $file = $args->{file}; + my $key = $args->{key} || "t."; + my $maxwidth = $args->{maxwidth} || 450; + my $maxheight = $args->{maxheight} || 450; + + my $filename = $file->{filename}; + my $lcfilename = thumbnail_filename($filename); + + use integer; + + $key = "t." if (!defined($key)); + print $file->{filename} if ($DEBUG); + + my ($xold, $yold) = imgsize(qq!$data_path/$file->{thread}/$filename!); + my $x = $xold; + my $y = $yold; + my @convert_args = (); + + push @convert_args, "$data_path/$file->{thread}/$filename"; + if ($filename =~ /.gif$/) { + push @convert_args, "-coalesce"; + } + push @convert_args, "-geometry"; + if ($maxheight < 1 && $maxwidth < 1) + { push @convert_args, "450x450"; } + elsif ($maxwidth < 1 || $key eq "b.") + { push @convert_args, "450x".$maxheight; } + elsif ($maxheight < 1) + { push @convert_args, $maxwidth; } + else + { push @convert_args, $maxwidth."x".$maxheight; } + + print "\n$filename -> .thumb/$key$lcfilename\n" if ($DEBUG); + print "old size: $xold x $yold\n" if ($DEBUG); + + if ($filename =~ /.gif$/) { + push @convert_args, "+map"; + } + push @convert_args, "$data_path/$file->{thread}/.thumb/$key$lcfilename"; + if ($DEBUG) + { print join " ", @convert_args; print "\n"; } + system($CONVERT_PATH, @convert_args); + system($CHMOD_PATH, 755, "$data_path/$file->{thread}/.thumb/$key$lcfilename"); + } + +# make a square thumbnail: +# crop bottom if portrait, crop sides if landscape +sub make_square_thumb + { + my ($file, $maxwidth, $key) = @_; + my $filename = $file->{filename}; + my $lcfilename = lc($file->{filename}); + my $_temp_thumb = $filename; + use integer; + + $key = "t." if (!defined($key)); + + # x = width, y = height + my ($xold, $yold) = imgsize(qq!$data_path/$file->{thread}/$file->{filename}!); + my $x = $xold; + my $y = $yold; + my $ydiff = 0; + my $xdiff = 0; + my @convert_args; + + if ($x != $y) # we must crop + { + if ($x < $y) + { + push @convert_args, "-crop", $x."x".$x; + $y = $x; + } + elsif ($y < $x) + { + $xdiff = ($x - $y) / 2; + push @convert_args, "-crop", $y."x".$y.'+'.$xdiff; + $x = $y; + } + + $_temp_thumb = ".thumb/temporary.jpg"; + push @convert_args, "$data_path/$file->{thread}/$filename"; + push @convert_args, "$data_path/$file->{thread}/$_temp_thumb"; + + print "\n$filename -> .thumb/$key$lcfilename\n" if ($DEBUG); + print "old size: $xold x $yold\n" if ($DEBUG); + print "new size: $x x $y\n" if ($DEBUG); + if ($DEBUG) + { print join " ", @convert_args; print "\n"; } + + system($CONVERT_PATH, @convert_args); + + for ($i = 0; $i < 4; $i++) + { + my $_temp_thumb_cropped = $_temp_thumb; + $_temp_thumb_cropped =~ s/.jpg$/-$i.jpg/; + ($xold, $yold) = imgsize(qq!$data_path/$file->{thread}/$_temp_thumb_cropped!); + if ($xold == $x) + { + $_temp_thumb = $_temp_thumb_cropped; + last; + } + } + } + @convert_args = (); + push @convert_args, "-geometry"; + push @convert_args, $maxwidth."x".$maxwidth; + push @convert_args, "$data_path/$file->{thread}/$_temp_thumb"; + push @convert_args, "$data_path/$file->{thread}/.thumb/$key$lcfilename"; + if ($DEBUG) + { print join " ", @convert_args; print "\n"; } + system($CONVERT_PATH, @convert_args); + system($CHMOD_PATH, 755, "$data_path/$file->{thread}/.thumb/$key$lcfilename"); + system($RM_PATH, "$data_path/$file->{parent_id}/.thumb/temporary.jpg"); + system($RM_PATH, "$data_path/$file->{parent_id}/.thumb/temporary-0.jpg"); + system($RM_PATH, "$data_path/$file->{parent_id}/.thumb/temporary-1.jpg"); + system($RM_PATH, "$data_path/$file->{parent_id}/.thumb/temporary-2.jpg"); + } + +sub print_image_thumb + { + my ($file, $thumb_token, $string) = @_; + + my $lcfilename = thumbnail_filename($file->{filename}); + + $thumb_token = "t." if (!defined($thumb_token)); + + print qq!<td align=center valign=middle>!; + + my $keyword = $file->{keyword} || "details"; + if ( $keyword == -1 ) + { $keyword = "details"; } + + if ($string == -1) + { print qq!<a href="$BUCKY/!.details_link().qq!/$file->{thread}">!; } + else + { print qq!<a href="$live_path/$file->{thread}/$file->{filename}">!; } + + print qq!<img class="thumb" border=0 src="$live_path/$file->{thread}/.thumb/$thumb_token!.$lcfilename.qq!">!; + print qq(</a>); + + if ($string != -1) + { + print qq(<br><small>); + if (length($file->{title})) + { print $file->{title}; } + else + { print clean_image_filename($file->{filename}); } + print qq! (! . profile_link($file->{username}) . qq!, ! . get_age($file->{date}) . qq!)!; + print qq(</small>); + } + + print qq!</a>!; + print qq!</td>!; + } + +sub clean_image_filename + { + my ($filename) = @_; + return if ($filename =~ /IMG|DSC/); + $filename =~ s/[-_]/ /g; + $filename =~ s/\....$//; + return $filename; + } + +sub curt_filename + { + my ($fn) = @_; + if (length($fn->{filename}) > 27 && $fn->{filename} !~ / /) + { + my $filen = substr $fn->{filename}, 0, 24; + my $filext = substr $fn->{filename}, -4, 4; + return "$filen..$filext"; + } + else + { return $fn->{filename}; } + } + +sub print_flagged_jpeg + { + my ($f) = @_; + my $lcfilename = thumbnail_filename($f->{filename}); + make_image_thumb( + { + file => $f, + maxwidth => 390, + # maxheight => 305, + key => "s." + } ) if (! -e qq!$data_path/$f->{thread}/.thumb/s.$lcfilename!); + print qq!<a href="$live_path/$f->{thread}/$f->{filename}"><img src="$live_path/$f->{thread}/.thumb/s.!.$lcfilename.qq!" class="thumb"></a>!; + } + +####################################################################################### +# image gallery building + +sub get_profile_image + { + my ($username, $prefix) = @_; + if (defined($prefix)) + { + if (-e $data_path."/profile/.thumb/$prefix$username.jpg") + { qq($live_path/profile/.thumb/$prefix$username.jpg) } + else + { qq($live_path/profile/.thumb/$prefix)."default".qq(.jpg) } + } + elsif (-e $data_path."/profile/$username.jpg") + { qq($live_path/profile/$username.jpg) } + else + { -1 } + } + +sub image_gallery + { + my ($files, $flagged, $many_jpgs) = @_; + my $i = 0; + my $j = 0; + print "<table border=0 cellpadding=3 cellspacing=0 width=100%>"; + foreach my $f (sort { $a->{date} <=> $b->{date} } @$files) + { + next if ($f->{filename} !~ /(jpe?g|gif|png|bmp|tif)$/i); + next if (($f->{id} == $flagged->{id}) && ($many_jpgs % 3) == 1); + + my $lcfilename = thumbnail_filename($f->{filename}); + make_image_thumb( { file => $f, maxwidth => 145, maxheight => 120, key => "t." }) + if (! -e qq($data_path/$f->{thread}/.thumb/t.).$lcfilename); + make_image_thumb( { file => $f, maxwidth => 210, maxheight => 110, key => "b." }) + if (! -e qq($data_path/$f->{thread}/.thumb/b.).$lcfilename); + + print "<tr>\n" if ($j == 0); + print_image_thumb($f, "t."); + print "</tr>\n" if ($j == 2); + + $j = $j == 2 ? 0 : $j+1; + + $i++; + } + print qq!</table>\n!; + return $i; + } + +sub image_column + { + my ($files, $flagged, $many_jpgs) = @_; + my $i = 0; + my $j = 0; + if ($many_jpgs > 5) + { $thumb_token = "t."; } + else + { $thumb_token = "b."; } + print qq(<table border=0 cellpadding=0 cellspacing=0>); + foreach my $f (sort { $a->{date} <=> $b->{date} } @$files) + { + next if ($f->{filename} !~ /(jpe?g|gif|png|bmp|tif)$/i); + next if ($f->{id} == $flagged->{id}); + + my $lcfilename = thumbnail_filename($f->{filename}); + make_image_thumb( { file => $f, maxwidth => 145, maxheight => 120, key => "t." }) + if (! -e qq($data_path/$f->{thread}/.thumb/t.).$lcfilename); + make_image_thumb( { file => $f, maxwidth => 210, maxheight => 110, key => "b." }) + if (! -e qq($data_path/$f->{thread}/.thumb/b.).$lcfilename); + + if ($many_jpgs-1 == 4) # tile in a square + { + if ($i % 2 == 0) + { + print qq(<tr>\n); + print_image_thumb($f, $thumb_token); + } + else + { + print_image_thumb($f, $thumb_token); + print qq(</tr>\n); + } + } + else + { + print qq(<tr>\n); + print_image_thumb($f, $thumb_token); + print qq(</tr>\n); + } + + $i++; + } + print qq!</table>\n!; + return $i; + } + +sub index_photostream + { + my ($keyword,$tag) = @_; +if (2 != 1) + { + photostream({ recent => 1, vertical => 0, count => $INDEX_GALLERY_IMAGE_COUNT }); + return; + } +else { + print "<table border=0 cellpadding=3 cellspacing=0 width=100%>"; +$i = 4; +print <<__CROWS__; +<td align=center valign=middle><a href="/cgi-bin/bucky/details/246"><img class="thumb" border=0 src="/bucky/data/246/.thumb/t.dsc_0253.jpg"></a></a></td> +<td align=center valign=middle><a href="/cgi-bin/bucky/details/246"><img class="thumb" border=0 src="/bucky/data/246/.thumb/t.dsc_0265.jpg"></a></a></td> +<td align=center valign=middle><a href="/cgi-bin/bucky/details/246"><img class="thumb" border=0 src="/bucky/data/246/.thumb/t.dsc_0240.jpg"></a></a></td> +<td align=center valign=middle><a href="/cgi-bin/bucky/details/246"><img class="thumb" border=0 src="/bucky/data/246/.thumb/t.dsc_0234.jpg"></a></a></td> +__CROWS__ + print "</table>\n"; +return; +} + if (check_key($USER->{boxes}, "photostream") || ($USER == -1) ) + { + if ( $keyword ne "all" ) + { photostream({ keyword => $keyword, vertical => 0, count => 4 }); } + elsif ( $tag ) + { photostream({ tag => $tag, vertical => 0, count => 4 }); } + else + { photostream({ user => 1, vertical => 0, count => 4 }); } + } + } + +sub photostream + { + my ($args) = @_; + my $vertical = $args->{vertical}; + my $count = $args->{count}; + my $user = $args->{user}; + my $recent = $args->{recent}; + my $keyword = $args->{keyword}; + my $tag = $args->{tag}; + if ( $recent ) + { + $args->{files} = get_recent_files(); + recent_image_gallery( $args ); + } + elsif ( $keyword ) + { + # TODO: privacy check + $args->{files} = get_keyword_files( $keyword ); + if ($args->{files} != -1) + { + user_image_gallery( $args ); + } + } + elsif ( $tag ) + { + $args->{files} = get_tag_files( $tag ); + if ($args->{files} != -1) + { + user_image_gallery( $args ); + } + } + else + { + for (my $i = 0; $i < 3; $i++) + { + my $username = get_random_user(); + $username = $BUCKY_ADMINISTRATOR if ($i == 2); + my ($count, $size) = count_user_files($username); + next unless ($count > 3); + $args->{files} = get_user_files( $username ); + if ($args->{files} != -1) + { + user_image_gallery( $args ); + return; + } + } + } + } + +sub recent_image_gallery + { + my ($args) = @_; + my $files = $args->{files}; + my $count = $args->{count} || 4; + my %seen; + print qq(<table border=0 cellpadding=0 cellspacing=0 width="100%" style='margin:0 0 10px 0'>); + print "<tr>"; + my $i = 0; + for my $f (@$files) + { + if (lc($f->{filename}) =~ /(jpe?g|gif|png)$/) { + if (! -e qq($data_path/$f->{thread}/.thumb/t.).lc($f->{filename})) { + make_image_thumb( { file => $f, maxwidth => 145, maxheight => 120, key => "t." }) + } + print_image_thumb($f, "t.", -1); + $i++; + last if ($i == $count); + } + } + print "</tr>" if (!$vertical); + print qq!</table>\n!; + } + +sub user_image_gallery + { + my ($args) = @_; + my $files = $args->{files}; + my $vertical = $args->{vertical} ? 1 : 0; + my $count = $args->{count} || 4; + my %seen; + print qq(<table border=0 cellpadding=3 cellspacing=3 width="100%">); + print "<tr>" if (!$vertical); + for (my $i = 0; $i < $count; $i++) + { + my $f = get_random_image($files, \%seen, $i); + last if ($f == -1); + make_image_thumb( { file => $f, maxwidth => 145, maxheight => 120, key => "t." }) + if (! -e qq($data_path/$f->{thread}/.thumb/t.).lc($f->{filename})); + print "<tr>" if ($vertical); + print_image_thumb($f, "t.", -1); + print "</tr>" if ($vertical); + print "\n"; + } + print "</tr>" if (!$vertical); + print qq!</table>\n!; + } + +sub get_random_image + { + my ($files, $seen, $i) = @_; + my $f; + $c = 0; + while ($f = $files->[(int rand @$files)]) + { + return -1 if ((++$c) == 69); + print "$i/$c: $f->{id} -- $f->{private} -- $seen->{$f->{id}}<br>" if ($DEBUG); + next if (exists($seen->{$f->{id}})); + $seen->{$f->{id}} = 1; + next if ($f->{filename} !~ /(jpe?g|gif|png|bmp|tif)$/i); + last if ( ( $USER == -1 && $f->{private} > 0 ) + || ( ref($USER) && $f->{private} > 1 ) ); + last; + } + return $f; + } + +sub find_jpeg + { + my ($files, $flagged_id) = @_; + my $flagged = -1; + my $fagid = -1; + my $i = 0; + my $j = 0; + foreach my $f (@$files) + { + if ($$f{filename} =~ /(jpe?g|gif|png|bmp|tif)$/i) + { + if ($$f{id} == $flagged_id || $flagged == -1) + { + $fagid = $$f{id}; + $flagged = $i; + } + $j++; + } + $i++; + } + if ($flagged > -1) + { + print_flagged_jpeg($files->[$flagged]) + } + return ($j, $fagid); + } + +sub find_jpeg_v2 + { + my ($files, $flagged_id) = @_; + my $flagged = -1; + my $fagid = -1; + my $i = 0; + my $j = 0; + foreach my $f (@$files) + { + if ($$f{filename} =~ /(jpe?g|gif|png|bmp|tif)$/i) + { + if ($$f{id} == $flagged_id || $flagged == -1) + { + $fagid = $$f{id}; + $flagged = $i; + } + $j++; + } + $i++; + } + if ($flagged > -1) + { return ($j, $files->[$flagged]); } + else + { return ($j, -1); } + } + +1; + + |
