#!/usr/bin/perl # semaphoreMovie # This script is a text to semaphore converter - it creates a QuickTime movie # showing the given message encoded using semaphore flags. # (http://en.wikipedia.org/wiki/Flag_semaphore). # The text is read from STDIN or from the files given as command-line arguments. # The image files are modified versions of those from the above Wikipedia page. # The sequence of images is turned into a movie using the "qt_tools" available # from http://omino.com/sw/qt_tools/ # # Cameron Hayne (macdev@hayne.net) August 2009 use strict; use warnings; use File::Path; my $wantAnnotated = 0; my $imageDir1 = 'FlagImages'; my $imageDir2 = 'FlagImagesAnnotated'; my %flags = ( # letters "a" => "Alpha", "b" => "Bravo", "c" => "Charlie", "d" => "Delta", "e" => "Echo", "f" => "Foxtrot", "g" => "Golf", "h" => "Hotel", "i" => "India", "j" => "Juliet", "k" => "Kilo", "l" => "Lima", "m" => "Mike", "n" => "November", "o" => "Oscar", "p" => "Papa", "q" => "Quebec", "r" => "Romeo", "s" => "Sierra", "t" => "Tango", "u" => "Uniform", "v" => "Victor", "w" => "Whisky", "x" => "X-ray", "y" => "Yankee", "z" => "Zulu", # numbers "0" => "Kilo", "1" => "Alpha", "2" => "Bravo", "3" => "Charlie", "4" => "Delta", "5" => "Echo", "6" => "Foxtrot", "7" => "Golf", "8" => "Hotel", "9" => "India", # special " " => "Ready", "#" => "Numeric", "@" => "Juliet", ); sub usageError() { my $options = "[-annotated]"; print STDERR "usage: semaphoreMovie $options [filename]\n"; exit(1); } sub handleCommandLineOptions() { use Getopt::Long; GetOptions( 'annotated' => \$wantAnnotated, ) or usage_error(); } # TODO: need to put a "rest" between doubled-letters in a word MAIN: { handleCommandLineOptions(); my $time = time(); my $seqDir = "Sequence$time"; my $imageDir = $wantAnnotated ? $imageDir2 : $imageDir1; undef $/; # slurp mode # get message in lowercase my $messageText = lc(<>); # change all non-alphanum to two spaces $messageText =~ s/[^a-z0-9]/ /g; # put a single space between doubled letters or digits $messageText =~ s/([a-z0-9])(?=\1)/$1 /g; # insert '#' for alpha to num transition $messageText =~ s/([a-z]\s*)(?=[0-9])/$1#/g; # insert '@' for num to alpha transition $messageText =~ s/([0-9]\s*)(?=[a-z])/$1@/g; #print "$messageText\n"; exit; my $numChars = length($messageText); my $maxDigits = 1 + int(log($numChars) / log(10)); mkdir $seqDir; chdir $seqDir or die "chdir failed: $!\n"; my $format = "char_%0${maxDigits}d.png"; my $count = 0; foreach my $ch (split(//, $messageText)) { my $filename = sprintf($format, $count++); symlink("../$imageDir/$flags{$ch}.png", "$filename") or die "symlink failed: $!\n"; } # now convert the sequence of images to a movie my $qtExport = '/usr/local/bin/qt_export'; my $seqRate = 1; my $options = " --sequencerate=$seqRate" . " --video=mjpa"; my $inputName = sprintf($format, 0); my $outputName = "movie${time}.mov"; my $command = "$qtExport $options $inputName ../$outputName"; system($command); chdir ".." or die "chdir failed: $!\n"; rmtree $seqDir; print "movie file: $outputName\n"; system("open $outputName"); }