stu96art has asked for the wisdom of the Perl Monks concerning the following question:

Howdy, ya'll. I have working code that I am trying to make shorter and more concise, as well as more efficient (faster). My code is a little long, but well documented and is located at stu96art's scratchpad .

I also have code that takes the information written from the final.txt file to create a graphical representation of the rectangles. I got this code to work for just one sheet, yet now I have expanded it to create multiple sheets. I need to create multiple sheets of the graphical representation. I am using GD for the graphics and when I was doing only one sheet, I needed only one object, I called im. So when I called my program from the command prompt, I used graphics.pl > im.png. There is no way to use this same system if I am going to have multiple object and multiple representations. Could someone help me with my code. Thanks, and any help is greatly appreciated.
use strict; use warnings; use GD; open ( OH, ">c:/printout1.txt" ) or die ("could not open file. &!" ); open ( GET, "<c:/final.txt" ) or die ("could not open file. &!" ); my ($im, $white, $black, $red, $blue, $green, $purple); my $buf; my (@values, @lines); # create a new image $im = new GD::Image(1000,1000); # allocate some colors $white = $im->colorAllocate(255,255,255); $black = $im->colorAllocate(0,0,0); $red = $im->colorAllocate(255,0,0); $blue = $im->colorAllocate(0,0,255); $green = $im->colorAllocate(0,255,0); $purple = $im->colorAllocate(100,0,175); # make the background transparent and interlaced $im->transparent($white); $im->interlaced('true'); # Put a black frame around the picture #$im->rectangle(0,0,99,99,$black); $im->fill(500,500,$purple); #$im->rectangle(0,0,100,100,$red); #$im->rectangle(100,100,200,200,$red); #$im->rectangle(200,200,300,300,$red); #$im->rectangle(300,300,400,400,$white); my $buffer = <GET>; chomp($buffer); my @big = split /\s+/, $buffer; my $maxx = $big[0]; my $maxy = $big[1]; my $count = 0; my $count2 = 1; my @abet; $abet[0] = "A"; $abet[1] = "A"; $abet[2] = "B"; $abet[3] = "C"; $abet[4] = "D"; $abet[5] = "E"; A:while ($buf = <GET>) { print OH "buf [$buf]\n"; if ($buf =~ /LITE2/) { AA:while ($buf = <GET>) { $count = $count + 1; chomp($buf); print OH "IN LITE2 buf [$buf]\n"; @values = split /\s+/, $buf; if ($buf =~/FINALLY/) { goto B; } print OH "START\n"; print OH "values 0[$values[0]] 1[$values[1]] 2[$values[2]] 3[$va +lues[3]]\n"; if ($values[4] == 0) { $count = 0; $count2 = $count2 + 1; next AA; } # end of if ($values[4] == 0) if ($values[4] == 1) { my $x0 = $values[2]*10; my $y0 = 1000 - ($values[3]*10) - $values[1]*10; my $x1 = ($values[2]*10) + ($values[0]*10); my $y1 = 1000 - ($values[3]*10); my $fx = $x0 + ( ($x1 - $x0) / 2); my $fy = $y0 + ( ($y1 - $y0) / 2); print OH "x0 [$x0] y0 [$y0] x1 [$x1] y1 [$y1]\n"; my $string = "$abet[$count2]-$count"; $im->rectangle($values[2]*10, 1000 - ($values[3]*10) - $value +s[1]*10 , ($values[2]*10)+($values[0]*10), 1000-($values[3]*10), $red + ); $im->string(gdMediumBoldFont,$fx,$fy,$string,$white); } # end of if ($values[4] == 1) } # end of while ($buf = <GET>) OUT: print OH "OUT\n"; } # end of if ($buf =~ /LITE2/) B:if ($buf =~ /FINALLY/) { while ($buf = <GET>) { @lines = split /\s+/, $buf; $im->line($lines[0]*10, 1000-($lines[1]*10), $lines[2]*10, 1000- +($lines[3]*10), $white); } # end of while ($buf = <GET>) } # end of if ($buf =~ /FINALLY/) } # end of while ($buf = <GET>) $im->line(0,1000-($maxy*10),$maxx*10,1000-($maxy*10),$white); $im->line($maxx*10,1000-($maxy*10),$maxx*10,1000,$white); # Put a black frame around the picture #$im->rectangle(0,0,99,99,$black); #$im->fill(50,50,$black); # Draw a blue oval #$im->arc(50,50,95,75,0,360,$green); # And fill it with red #$im->fill(50,50,$purple); # make sure we are writing to a binary stream binmode STDOUT; # Convert the image to PNG and print it on standard output print $im->png;

Replies are listed 'Best First'.
Re: Help with efficiency
by Abigail-II (Bishop) on May 12, 2004 at 23:04 UTC
    It's not clear to me what your problem is. Is your problem that you currently have just one $im, but want more? In that case, you should probably use an array. Or is your problem that you have to write to multiple files? In that case, instead of writing to STDOUT, open one or more files yourself (using the open function) and write to the filehandles using print.

    Abigail

      My problem is that I have an unknown number of "sheets" or objects that I am trying to create. I want to create different graphic files for each object. What I am using now works, but I use the command prompt to tell the object information where to go, graphics.pl > im.png . I do not know how to adjust where the object information will go to so that it can change with different objects. Thanks for your help
        What I am using now works, but I use the command prompt to tell the object information where to go, graphics.pl > im.png
        Instead of printing your single object to STDOUT, you'll need to print out each object inside your code.

        This will result in code roughly like the following:

        use strict; use warnings; my $i = 1; # The object number we're up to # create object 1 somehow open(FILE, ">", "object$i.png") or die "Failed to open object$i.png: $ +!"; # make sure we are writing to a binary stream binmode FILE; # Convert the image to PNG and print it to file print FILE $im->png; $i++; # create object 2 somehow, rinse and repeat
        You may put all of that in a loop, or you may create an output subroutine, you may even choose to do all the printing at the end... But you're going to need to do the printing to files inside your program rather than capturing STDOUT and redirecting that to a file.

        Keep in mind that using open with > will result in any previous data in the file called "object$i.png" to be overwritten. You can use the following test if this might be a problem:

        my $filename = "object$i.jpg"; if(-e $filename) { die "$filename already exists in this directory\n"; # or something more useful. } open(FILE, ">", $filename) or die "Failed to open $filename: $!";

        I hope this helps

        jarich

        Well, just as I said, open the files you want to write to in your program, and write to them.

        Abigail