PHP GD Library shades are gone

Hi I am using PHP GD library to replace a color. It is changing the color but the shades are gone.

Original Image(white).

Color replaced Image(red):

How can I keep the shades in the generated image?

Can you post the code you have written?

@cpradio
This is the color replacement code. Thanks.

function replaceColor(&$img,$newColor) {

        $w = imagesx($img);
        $h = imagesy($img);
        
        // Work through pixels
        for ($y = 0; $y < $h; $y++) {
            for ($x = 0; $x < $w; $x++) {
                // Apply new color + Alpha
                $rgb = imagecolorsforindex($img, imagecolorat($img, $x, $y));

                $transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
                imagesetpixel($img, $x, $y, $transparent);


                // Here, you would make your color transformation.
                $red_set = $newColor[0] / 100 * $rgb['red'];
                $green_set = $newColor[1] / 100 * $rgb['green'];
                $blue_set = $newColor[2] / 100 * $rgb['blue'];
                if ($red_set > 255)
                    $red_set = 255;
                if ($green_set > 255)
                    $green_set = 255;
                if ($blue_set > 255)
                    $blue_set = 255;

                $pixelColor = imagecolorallocatealpha($img, $red_set, $green_set, $blue_set, $rgb['alpha']);
                imagesetpixel($img, $x, $y, $pixelColor);
            }
        }

        // Restore Alpha
        imageAlphaBlending($img, true);
        imageSaveAlpha($img, true);

    }

And are you using { 255, 0, 0} for $newColor?

Yeah

Okay, first thing I’ve done is started a bunch of output, as that typically helps me see what is going on. I’m just coping a snippet to prove my point, so hold tight as I explain what it means.

Position: 158, 0; RGB Detected: 210, 152, 115; Calculated Color: 535.5, 0, 0; Established Color: 255, 0, 0; Alpha: 127
Position: 159, 0; RGB Detected: 209, 145, 109; Calculated Color: 532.95, 0, 0; Established Color: 255, 0, 0; Alpha: 125
Position: 160, 0; RGB Detected: 207, 143, 107; Calculated Color: 527.85, 0, 0; Established Color: 255, 0, 0; Alpha: 125
Position: 161, 0; RGB Detected: 207, 144, 109; Calculated Color: 527.85, 0, 0; Established Color: 255, 0, 0; Alpha: 125
Position: 162, 0; RGB Detected: 201, 141, 105; Calculated Color: 512.55, 0, 0; Established Color: 255, 0, 0; Alpha: 126
Position: 163, 0; RGB Detected: 201, 141, 104; Calculated Color: 512.55, 0, 0; Established Color: 255, 0, 0; Alpha: 126
Position: 164, 0; RGB Detected: 194, 134, 97; Calculated Color: 494.7, 0, 0; Established Color: 255, 0, 0; Alpha: 125
Position: 165, 0; RGB Detected: 190, 132, 95; Calculated Color: 484.5, 0, 0; Established Color: 255, 0, 0; Alpha: 126
Position: 166, 0; RGB Detected: 181, 127, 93; Calculated Color: 461.55, 0, 0; Established Color: 255, 0, 0; Alpha: 127

So the position relates to an X/Y coordinate sent to imagecolorat (for a cropped version of your tshirt.png I created).

The RGB detected is the value of $rgb for that position, The Calculated Color is what is determined immediately after the following code:

			// Here, you would make your color transformation.
			$red_set = $newColor[0] / 100 * $rgb['red'];
			$green_set = $newColor[1] / 100 * $rgb['green'];
			$blue_set = $newColor[2] / 100 * $rgb['blue'];

The Established Color is the value of each color set after the IF blocks, finally Alpha represents the value of [‘alpha’] from $rgb.

Okay, from what you can see, the calculation is horribly gone wrong. I’m still trying to figure out the right calculation to use, but that is where we need to start. As the calculated color is well over the RGB range all of the time! So bear with me as I work through it some more (if you have ideas, feel free to look at it on your end too).

Bingo!

function replaceColor(&$img,$newColor) {

	$w = imagesx($img);
	$h = imagesy($img);

	// Work through pixels
	for ($y = 0; $y < $h; $y++) {
		for ($x = 0; $x < $w; $x++) {
			//echo "Position: $x, $y; ";
			// Apply new color + Alpha
			$rgb = imagecolorsforindex($img, imagecolorat($img, $x, $y));

			//echo "RGB Detected: {$rgb['red']}, {$rgb['green']}, {$rgb['blue']}; ";
			$transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
			imagesetpixel($img, $x, $y, $transparent);


			// Here, you would make your color transformation.
			$red_set = ($rgb['red'] / 255) * $newColor[0]; //$newColor[0] / 100 * $rgb['red'];
			$green_set = ($rgb['green'] / 255) * $newColor[1]; //$newColor[1] / 100 * $rgb['green'];
			$blue_set = ($rgb['blue'] / 255) * $newColor[2]; //$newColor[2] / 100 * $rgb['blue'];

			//echo "Calculated Color: $red_set, $green_set, $blue_set; ";
			if ($red_set > 255)
				$red_set = 255;
			if ($green_set > 255)
				$green_set = 255;
			if ($blue_set > 255)
				$blue_set = 255;

			//echo "Established Color: $red_set, $green_set, $blue_set; Alpha: {$rgb['alpha']}<br />";
			$pixelColor = imagecolorallocatealpha($img, $red_set, $green_set, $blue_set, $rgb['alpha']);
			imagesetpixel($img, $x, $y, $pixelColor);
		}
	}

	// Restore Alpha
	imageAlphaBlending($img, true);
	imageSaveAlpha($img, true);

}

Red T-shirt

Wow…I tried it many times and felt bored and went of my PC.

I feel like kissing you. Man you are man and GREAT GREAT HELPER. I just love you.

Just Awesome. Thanks.