#!/usr/bin/perl -w #nathan jahnke use Image::Magick; use Statistics::Descriptive; $source = '/Volumes/l/h'; $out = '/Volumes/l/o'; for ($source, $out) { $_ = shift @ARGV or die "Usage: $0 sourcedir destdir"; } $ext='png'; #info about the original video $fps=30; #info about the destination video $destwidth=512; $destheight=384; #number of seconds to average crop values $interval=2; #default fuzz% value #started with 10 but that seemed to get a lot of false positives with bloom from the screen in bright areas $defaultfuzz = 30; $fuzz = $defaultfuzz; #$width and $height are set automatically from first image below # $width=640;#expected width of input # $height=480;#expected height of input #you can override these here, otherwise they are set automatically below # $topmax = 0; # $leftmax = 0; # $rightmax = 0; # $bottommax = 0; my $image = Image::Magick->new(magick=>'png'); opendir(PIX,$source); @pix = grep { /\.${ext}$/ } readdir(PIX); closedir(PIX); $count=0; for (@pix) { #next if !/\.${ext}$/; print $_, "\n"; if ($count == 0) { #[re]initialize stats objects $lefto = Statistics::Descriptive::Full->new(); $righto = Statistics::Descriptive::Full->new(); $topo = Statistics::Descriptive::Full->new(); $bottomo = Statistics::Descriptive::Full->new(); } $count++; open( my $frame, "${source}/${_}" ) or die $!; my $framedata = do { local( $/ ) ; <$frame> } ; close($frame); $image->BlobToImage($framedata); if (!($width && $height)) { ($width, $height) = $image->Get('width','height'); #set crop maximums if not already set above - default is half the image width/height since the screen is unlikely to not take up at least most of the frame $topmax = ($height / 2) if !defined $topmax; $leftmax = ($width / 2) if !defined $leftmax; $rightmax = ($width / 2) if !defined $rightmax; $bottommax = ($height / 2) if !defined $bottommax; } $image->Trim(fuzz => $fuzz.'%'); my $page = $image->Get('page'); my ($left, $top) = ($page =~ m/^\d+x\d+\+(\d+)\+(\d+)$/); my ($currentwidth, $currentheight) = $image->Get('width','height'); my ($right, $bottom) = ( (640-$currentwidth), (480-$currentheight) ); if (!($right && $left && $top && $bottom)) { #autocrop failed to crop something if ($fuzz < 100) { #try again with higher "fuzz" value $fuzz+=2; #could increment by just one but it's god awful slow (22 march 2009) $count--; @$image = (); #redo doesn't go through continue block redo; } else { #or give up, if we've already tried up to 100% fuzz and still can't crop push(@imagebuffer,$_,$framedata); next; #screw this frame } } elsif ( #do any of the trim values exceed our maximums? ($top > $topmax) || ($left > $leftmax) || ($right > $rightmax) || ($bottom > $bottommax) ) { #setting fuzz higher won't help; bail on this frame push(@imagebuffer,$_,$framedata); next; #screw this frame } push(@imagebuffer,$_,$framedata); print " ${top}\n"; print "${left} ${right}\n"; print " ${bottom}\n"; print "\n"; for my $stat ( [$lefto, $left ], [$righto, $right ], [$topo, $top ], [$bottomo, $bottom ], ) { $$stat[0]->add_data($$stat[1]); #print "\n".$topo->count()."\n"; } if (($count >= ($interval*$fps)) || ($_ eq $pix[-1])) { #is this the last frame? $count=0; print "\n\nMean\n"; print " ".sprintf("%.0f",$topo->mean)."\n"; print sprintf("%.0f",$lefto->mean)." ".sprintf("%.0f",$righto->mean)."\n"; print " ".sprintf("%.0f",$bottomo->mean)."\n"; print "\n\n\n"; my $leftmean = sprintf("%.0f",$lefto->mean); my $topmean = sprintf("%.0f",$topo->mean); my $newwidth = ($width - sprintf("%.0f",$righto->mean)); my $newheight = ($height - sprintf("%.0f",$bottomo->mean)); while (my $filename = shift @imagebuffer) { my $imagedata = shift @imagebuffer or die $!; @$image = (); $image->Read(blob => $imagedata); $image->Crop(geometry => #argh, i want my avisynth $newwidth .'x'.$newheight .'!' #ignore aspect ratio .'+'.$leftmean .'+'.$topmean ); $image->Resize(geometry => $destwidth.'x'.$destheight.'!', filter=> 'Lanczos'); $image->Write("${out}/${filename}"); } } } continue { $fuzz=$defaultfuzz; @$image = (); } exit 0;