Colorize PNG using PHP GD

300 Views Asked by At

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

3

There are 3 best solutions below

1
miken32 On

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

0
miken32 On

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

0
AudioBubble On

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