1

I want to colorize some PNGs using PHP GD. For testing purpose i hardcoded the color red (255,0,0) which later will be replace by a dynamic variable.

For example i have these two images:

Image 1: 6Bt.png

Image 2: 6Bd.png

Using my code, only image 2 works as it should. 6BC.png

The dog image however has some sort of gray box, don't know where the heck this comes from. 6BA.png

Here is the code I'm using:

<?php

$im = imagecreatefrompng('dog.png');

imagealphablending($im, false);
imagesavealpha($im, true);

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

for ($x = 0; $x < $w; $x++) {
    for ($y = 0; $y < $h; $y++) {
        $color = imagecolorsforindex($im, imagecolorat($im, $x, $y));

        $r = ($color['red'] * 255) / 255;
        $g = ($color['green'] * 0) / 255;
        $b = ($color['blue'] * 0) / 255;

        imagesetpixel($im, $x, $y, imagecolorallocatealpha($im, $r, $g, $b, $color['alpha']));
    }
}

imagepng($im, 'result.png');
imagedestroy($im);

Why does it work with image 2 but not image 1? I only can think of some sort of alpha mask going on with image 1.

Hope somebody can help me

miken32
  • 42,008
  • 16
  • 111
  • 154

3 Answers3

1

This could be more easily done using imagefilter():

<?php
$im = imagecreatefrompng('dog.png');
imagefilter($im, IMG_FILTER_COLORIZE, 255, 0, 0);
imagepng($im, 'result.png');
imagedestroy($im);

Result: enter image description here

miken32
  • 42,008
  • 16
  • 111
  • 154
0

It's not mentioned in the documentation for imagecolorallocate() or its alpha equivalent, but someone has pointed out in the comments that you can only allocate 255 colours in the image before running out. Check that the allocation hasn't failed before using the new colour. If it has, use imagecolorclosestalpha() to get the next best thing.

<?php
$replace = [255, 0, 0];
array_walk($replace, function(&$v, $k) {$v /= 255;});

$im = imagecreatefrompng('dog.png');

for ($x = 0; $x < imagesx($im); $x++) {
    for ($y = 0; $y < imagesy($im); $y++) {
        $color = imagecolorsforindex($im, imagecolorat($im, $x, $y));

        $r = $color["red"] * $replace[0];
        $g = $color["green"] * $replace[1];
        $b = $color["blue"] * $replace[2];
        $a = $color["alpha"];
        $newcolour = imagecolorallocatealpha($im, $r, $g, $b, $a);
        if ($newcolour === false) {
            $newcolour = imagecolorclosestalpha($im, $r, $g, $b, $a);
        }
        imagesetpixel($im, $x, $y, $newcolour);
    }
}

imagepng($im, 'result.png');
imagedestroy($im);

Output: enter image description here

miken32
  • 42,008
  • 16
  • 111
  • 154
0

I'v got it working using my code. All i had to do is add imagepalettetotruecolor($im);