Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - Replace colour within image

I hope someone can help,

I have made a script that masks images... however it is reliant on a colour to mask with ( 'green screen' style). The trouble is if the image that I am masking contains that colour it is ruined.

What I am looking to do is prior to masking the image replace any occurance of my keying colour (0,0,255) with a similar colour such as 0,0,254.

I have found a few solutions based around gif's or 256 colour PNG as they are indexed..

So my question is also will it be more efficient to convert it to a gif or 256 png then look through the index and replace the colour or search through every pixel and replace the colours.

Thanks,

like image 318
Mark Avatar asked Oct 10 '09 17:10

Mark


2 Answers

You need to open the input file and scan each pixel to check for your chromokey value.

Something like this:

// Open input and output image
$src = imagecreatefromJPEG('input.jpg') or die('Problem with source');
$out = ImageCreateTrueColor(imagesx($src),imagesy($src)) or die('Problem In Creating image');

// scan image pixels
for ($x = 0; $x < imagesx($src); $x++) {
    for ($y = 0; $y < imagesy($src); $y++) {
        $src_pix = imagecolorat($src,$x,$y);
        $src_pix_array = rgb_to_array($src_pix);

            // check for chromakey color
            if ($src_pix_array[0] == 0 && $src_pix_array[1] == 0 && $src_pix_array[2] == 255) {
                $src_pix_array[2] = 254;
            }


        imagesetpixel($out, $x, $y, imagecolorallocate($out, $src_pix_array[0], $src_pix_array[1], $src_pix_array[2]));
    }
}


// write $out to disc

imagejpeg($out, 'output.jpg',100) or die('Problem saving output image');
imagedestroy($out);

// split rgb to components
function rgb_to_array($rgb) {
    $a[0] = ($rgb >> 16) & 0xFF;
    $a[1] = ($rgb >> 8) & 0xFF;
    $a[2] = $rgb & 0xFF;

    return $a;
}
like image 75
radio4fan Avatar answered Oct 27 '22 09:10

radio4fan


Here is the replace colour solution that first converts to 256 pallet:

//Open Image
$Image = imagecreatefromJPEG('input.jpg') or die('Problem with source');

//set the image to 256 colours
imagetruecolortopalette($Image,0,256);

//Find the Chroma colour
$RemChroma = imagecolorexact( $Image,  0,0,255 );

//Replace Chroma Colour
imagecolorset($Image,$RemChroma,0,0,254);

//Use function to convert back to true colour
imagepalettetotruecolor($Image);




function imagepalettetotruecolor(&$img)
    {
        if (!imageistruecolor($img))
        {
            $w = imagesx($img);
            $h = imagesy($img);
            $img1 = imagecreatetruecolor($w,$h);
            imagecopy($img1,$img,0,0,0,0,$w,$h);
            $img = $img1;
        }
    }

I personally prefer radio4fans solution as it is lossless, but if speed is your goal this is superior.

like image 2
Mark Avatar answered Oct 27 '22 08:10

Mark