in reply to Cannot Set Image Pixel to a Random Colour using GD
I assume your intent is to open and save "true colour" RGB, 8 bits per channel images, as opposed to paletted images. "Learning curve" or not, you'll get nowhere before you understand the difference, so as not to try to use methods designed for paletted images on "true colour" images.
trueColor is class method; GD documentation is clear about that. However, it also says that, by default, "true colour" GD object is created if PNG already was "true colour". It's not what I observe. Instead of calling class method before opening anything, I'd suggest providing an explicit flag to constructor, as in example below.
Using Imager just to desaturate triplets of values, while at the same time using GD to manipulate an image is so wrong on all sides, that I simply chose to use another distribution for the purpose. The Convert::Color and Colouring::In are what searching the CPAN reveals (the latter even provides the desaturate method); but you can continue to use Imager, of course. If it's all just for exercise, it may (or may not) be beneficial to write RGB to HSV (and back) conversions yourself. If it's not just an exercise, I'd strongly advise not to get and set pixels one by one in high level language.
Note that getPixel returns large integer in case of "true color", which is just packed BGR triplet. The "convert" is ImageMagick's executable supposed to be in the PATH. + Actually calling reverse twice isn't required to only mess with saturation alone.
use strict; use warnings; use feature 'say'; use open IO => ':raw'; use GD; use Convert::Color; sub desaturate { local $" = ','; my @HSV = Convert::Color-> new( "rgb8:@_" )-> as_hsv-> hsv; $HSV[ 1 ] *= 0.7; return Convert::Color-> new( "hsv:@HSV" )-> as_rgb8-> rgb8 } my $gd = GD::Image-> newFromPngData( scalar qx/convert rose: png:-/, 1 + ); for my $y ( 0 .. $gd-> height - 1 ) { for my $x ( 0 .. $gd-> width - 1 ) { my $packed_rgb = $gd-> getPixel( $x, $y ); my @RGB = reverse unpack 'C3', pack 'L', $packed_rgb; $packed_rgb = unpack 'L', pack 'C3x', reverse desaturate( @RGB + ); $gd-> setPixel( $x, $y, $packed_rgb ) } } open my $fh, '>', 'desaturated_rose.png' or die; binmode $fh; print $fh $gd-> png; close $fh;
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Cannot Set Image Pixel to a Random Colour using GD
by ozboomer (Friar) on Dec 25, 2022 at 10:35 UTC |