in reply to Image Editing with GD

By default, for backwards compatibility with earlier versions of GD, images are created as 8-bit palletised. To get 24-bit color (truecolor), you need to indicate that you want this when you create the image, or afterwards using the $img->truecolor( 1 ); method.

Change your image creation line to

my $outpizzle = GD::Image->new( $width, $height, 1 );

and observe the difference it makes to your output.

Also, faking #use strict; serves no purpose whatsoever :) It took all of 10 seconds to do it properly.

#!/usr/bin/perl use strict; use GD; my $width = 800; my $height = 600; my $outpizzle = new GD::Image( $width, $height, 1 ); #$outpizzle->interlaced('true'); #define a $%!@ ton of colors ... bad idea? my @colors; for ( my $i=0; $i<10; $i++) { for ( my $j=0; $j<10; $j++) { for ( my $k=0; $k<10; $k++) { $colors[$i][$j][$k] = $outpizzle->colorAllocate($i*25,$j*2 +5,$k*25); } } } #draw some shizzle for ( my $i=0; $i<$width; $i++) { for ( my $j=0; $j<$height; $j++) { $outpizzle->setPixel($i,$j,$colors[int(10*($i/$width))][int(10 +*($j/$height))][0]); #print int(10*($i/$width))+"\n"; } } #output the picture open(PICTURE, ">picture.png") or die("uh oh spaghettio"); binmode PICTURE; print PICTURE $outpizzle->png; close PICTURE; ## display result on win32 systems system 'picture.png';

There are lots of other things that could be 'improved', but it's your code.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^2: Image Editing with GD
by alanonymous (Sexton) on Nov 10, 2006 at 12:36 UTC
    Thank you much for the help. I didn't realize it could have been as easy as adding a '1'.

    As far as the strict goes, it was just a reminder to do things correctly later :) I know I'm a bad programmer but I'm trying at least.

    As far as things that can be done differently go, is there an easier way to set a pixel to a specific color, without first creating that color with colorAllocate? I mean, it seems silly to me for it to not be easier. Using any more than 8 bits of color pixel by pixel seems like it would take forever to run.

    Thanks again for the help.

    -Alan

      When using truecolor images, I've found that I can skip the colorAllocate() step by specifying the packed rgb value inplace of the index. I use

      sub rgb{ unpack 'N', pack 'xCCC', @_ }

      for this, though the name is probably a misnomer.

      I'm not sure if this is documented anywhere, and cpan seems to be down at the moment, so I haven't been able to check. It seems to work okay with GD v2.30. It's also a lot faster and more convenient than using colorAllocate() to build an rbg->index table.

      This is a simpler, faster version of your original that uses the above:

      #!/usr/bin/perl -slw use strict; use GD; sub rgb{ unpack 'N', pack 'xCCC', @_ } my $width = 800; my $height = 600; my $img = new GD::Image( $width, $height, 1 ); for my $x ( 0 .. $width -1 ) { for my $y ( 0 .. $height -1 ) { $img->setPixel( $x, $y, rgb( $x * 255 / $width, $y * 255 / $height, 0 ) ); } } open my $fh, '>:raw', 'picture.png' or die "uh oh spaghettio : $!"; print $fh $img->png; close $fh; ## display result on win32 systems system 'picture.png';

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Thank you for the help! This is exactly what I was looking for!

        -Alan

      Dunno that much about GD, but you can make your code more efficient like so:

      use GD; my $width = 800; my $height = 600; my $img = new GD::Image($width,$height,1); #draw some shizzle for (my $i=0; $i<=$width; $i++) { # calc $i colour only when $i changes my $icol = int(($i*255)/$width); for (my $j=0; $j<=$height; $j++) { # calc colorAllocate here and lose previous loop # also, no need to calc 3rd colour param $img->setPixel($i,$j,$img->colorAllocate($icol,int(($j*255)/$heigh +t),0)); } } #output the picture open(PICTURE, ">$test.png") or die("uh oh spaghettio"); binmode PICTURE; print PICTURE $img->png; close PICTURE;

      <update>wasn't black to red...</update>

      <update>...and we don't need @colors anymore...</update>

      Tom Melly, tom@tomandlu.co.uk