Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- #--------------------------------------------------------------------------
- # This script is a modification of a pre-existing script.
- # The modifications are by Phillip J Rhoades.
- # howtophil@gmail.com
- #
- # It is based on this script: https://github.com/plurSKI/imageSpectrogram
- # http://www.devrand.org/2013/04/image-to-spectrogram.html by Gavin Black
- #
- # The original script created "hidden" spectrogram images.
- #
- # The modifications are for creating waterfall images in fldigi
- # and similar programs. Since I've made quite a few changes, I've
- # renamed the perl script to denote its different purpose.
- #
- # Please use waterfallpre.sh to "prep" images for transformation
- # into waterfall sstv images. Or use GIMP (Ph*t*sh*p, whatever).
- # I find gray scale images work best. Fiddle with the contrast
- # and brightness and make a few test runs.
- #
- # ./waterfallpre.sh "imagename.jpg" 150
- #
- # This will generate 150-imagename.jpg
- #
- # 10 pixels wide is about 100hz in the fldigi waterfall.
- # So, you'll want to keep images 200ish or fewer pixels
- # wide in most cases.
- #
- # I'm not your dad though, so do as you like.
- #
- # After your image is ready run:
- #
- # ./imageWaterfall.pl "150-imagename.jpg" <output_file> <sound_frequency_center>
- #
- # You will then have a wav file which will create a lossy image
- # in the fldigi (and similar programs) waterfall display
- # when received. Amaze your friends! Be the King Geek and The Dork God!
- #
- #--------------------------------------------------------------------------
- use strict;
- use Audio::Wav;
- use Math::Complex;
- use GD;
- use constant TWO_PI => pi() * 2;
- my $wav = Audio::Wav->new();
- my $sample_rate = 44100;
- my $bits_sample = 16;
- my $freq_Center = $ARGV[2] || 1500;
- my $y = 1;
- print "$freq_Center";
- if( $#ARGV < 0 )
- {
- print "Usage: $0 input_file <output_file> <sound_frequency_center>\n";
- exit 0;
- }
- # Start writing the wave with the proper arguments
- write_out(( $#ARGV < 1) ? "$ARGV[0].wav" : $ARGV[1], $ARGV[0]);
- sub write_out
- {
- # Set up the wave file
- my $filename = shift;
- my $write = $wav->write($filename, {
- bits_sample => $bits_sample,
- sample_rate => $sample_rate,
- channels => 1,
- });
- # Set up the picture to read from
- my $imageName = shift;
- my $srcimage;
- open FILE, $imageName or die "Couldn't open: $imageName\n";
- close(FILE);
- my $ucImage = uc $imageName;
- if( $ucImage =~ m/.JPG/ || $ucImage =~ m/.JPEG/ )
- {
- $srcimage = GD::Image->newFromJpeg($imageName);
- } elsif ( $ucImage =~ m/.PNG/ ) {
- $srcimage = GD::Image->newFromPng($imageName);
- } elsif ( $ucImage =~ m/.GIF/ ) {
- $srcimage = GD::Image->newFromGif($imageName);
- } else {
- print "Unsupported filetype\nMust be png, jpg, jpeg, bmp, or gif\n";
- exit -1;
- }
- my ($srcW,$srcH) = $srcimage->getBounds();
- # Step through each pixel
- #for( my $x = 0; $x < $srcW; $x ++ )
- #for( my $x = 0; $x < $srcH; $x ++ )
- for( my $x = $srcH; $x > 0; $x -- )
- {
- my @t = ();
- #for( my $y = 0; $y < $srcH; $y ++ )
- for( my $y = $srcW; $y > 0; $y -- )
- {
- my $index = $srcimage->getPixel($y,$x);
- my ($r,$g,$b) = $srcimage->rgb($index);
- # Set the frequency and 'color' for this pixel. Ignore if black
- if( $r > 10 || $g > 10 && $b > 10 )
- {
- #my $c = 4.25 - 4.25*($r + $g + $b)/(256*3);
- my $c = 4.25 - 4.25*($r + $g + $b)/(256*3);
- if( $c < 0.75 )
- {
- $c = 0.75;
- }
- #print "$c\n";
- #push( @t, int(2000 - ( $y + 1)/( $srcH + 1) * 1800) );
- #push( @t, int(2000 - ( $y + 1)/( $srcH + 1) * ( ( $srcH * 10 ) - $srcH ) ) );
- #push( @t, int( ( $freq_Center + ( $srcH * 5 ) - ( $srcH / 2) ) - ( $y + 1)/( $srcH + 1) * ( ( $srcH * 10 ) - $srcH ) ) );
- push( @t, int( ( $freq_Center - ( $srcW * 5 ) + ( $srcW / 2) ) + ( $y + 1)/( $srcW + 1) * ( ( $srcW * 10 ) - $srcW ) ) );
- #push( @t, int(($y/$srcH)+1000) );
- push( @t, $c );
- }
- }
- # Ugly way to show a status percentage
- my $status = int(100*$x/$srcH);
- my $lowstatus = 100 - $status;
- my $statusDec = int(10000*$x/$srcH) - 100 * $status;
- my $lowstatusDec = 100 - $statusDec;
- print "\b\b\b\b\b\b\b\b\b\b\b\b$lowstatus.$lowstatusDec% ";
- $| = 1;
- # Add a .23 second set of sine waves
- add_sine($write, .23, @t);
- }
- # Finish up
- print "\b\b\b\b\b\b\b\b\b\b\b\b\b100% \n";
- $write->finish();
- }
- sub add_sine {
- my ($write,$length,@freqs) = @_;
- my $max_no = (2 ** $bits_sample) / 2;
- $length *= $sample_rate;
- for my $pos (0..$length) {
- my $count = 0;
- my $val = 0;
- for( $count = 0; $count < @freqs.length; $count += 2)
- {
- my $time = ($pos / $sample_rate) * @freqs[$count];
- $val += sin(TWO_PI * $time)*10/(10 ** @freqs[$count + 1]);
- }
- $val /= $count+1;
- my $samp = $val * $max_no;
- $write->write($samp);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement