Image Color Replacement Technique

GD and GD2 are useful libraries for creating graphics on-the-fly. Discuss your PHP GD and GD2 scripts here.

Moderators: onion2k, General Moderators

Image Color Replacement Technique

Postby ahsanra » Fri Jan 20, 2006 2:00 am

Hi.
i have a problem i am trying to develope a code that will allow users to change the one specific color of a bitmap image to any specific color they want.

SO for this i need some technique that can help me change the colors of pixels in an image to my desired color.

How can that be possible ?

Any help shall really be appreciated.

Regards,
Ahsan
ahsanra
Forum Newbie
 
Posts: 9
Joined: Fri Jan 20, 2006 1:57 am

Postby onion2k » Fri Jan 20, 2006 4:32 am

It depends on the type of image being uploaded ..

For a GIF or an 8bit PNG you can change the specific color in the palette:
Syntax: [ Download ] [ Hide ]
<?php



        $image = imagecreatefromgif("heart.gif");



        $colorToChange = "FF0000";

        $newColor = "0000FF";



        $c1 = sscanf($colorToChange,"%2x%2x%2x");

        $c2 = sscanf($newColor ,"%2x%2x%2x");



        $cIndex = imagecolorexact($image,$c1[0],$c1[1],$c1[2]);

        imagecolorset($image,$cIndex,$c2[0],$c2[1],$c2[2]);



        header("Content-Type: image/png");

        imagepng($image);



?>

For a true color image, either jpeg or PNG:
Syntax: [ Download ] [ Hide ]
<?php



        $image = imagecreatefromjpeg("heart.jpg");

        $width = imagesx($image);

        $height = imagesy($image);



        $colorToChange = "FE0000";

        $newColor = "0000FF";



        $c1 = sscanf($colorToChange,"%2x%2x%2x");

        $c2 = sscanf($newColor,"%2x%2x%2x");

       

        $cnew = imagecolorallocate($image,$c2[0],$c2[1],$c2[2]);



        for ($y=0;$y<$height;$y++) {

                for ($x=0;$x<$width;$x++) {

                        $rgb = imagecolorat($image,$x,$y);

                        $r = ($rgb >> 16) & 0xFF;

                        $g = ($rgb >>  & 0xFF;

                        $b = $rgb & 0xFF;

                        if (($r==$c1[0]) && ($g==$c1[1]) && ($b==$c1[2])) {

                                imagesetpixel($image,$x,$y,$cnew);

                        }

                }

        }

       

        header("Content-Type: image/png");

        imagepng($image);



?>

Bear in mind that this will do exactly what you're asking for. It will change one specific color to a different one. It you want to change a range of colors (eg all the reds) then you'll need to make the color matching a bit fuzzier.
User avatar
onion2k
Jedi Mod
 
Posts: 5263
Joined: Tue Dec 21, 2004 6:03 pm
Location: usrlab.com

Postby AKA Panama Jack » Fri Jan 20, 2006 4:40 am

Just remember that your server will have to have the GD Library installed and the appropriate graphics library (libpng, libjpg, ect) installed as well.
User avatar
AKA Panama Jack
Forum Regular
 
Posts: 878
Joined: Mon Nov 14, 2005 5:21 pm

Postby ahsanra » Fri Jan 20, 2006 6:20 am

Thanks alot jason,

I really appreciate your help.

I would like you to help me in one another task .. how can i read all the colors that are available in an image (i am only working with PNG, BMP and TIF) and fill them in a drop down box.

I need them becasue i want my system to be completely dynamic .. it will read all the colors that are present in the image and then choosing the specific image color from one drop down and other color from another drop down with is filled with custom colors. And the system will replace the color from first drop down with the one present in another drop down.

Please help me how can i read all the colors present in an image ?

Thanks in advance.

Ahsan
ahsanra
Forum Newbie
 
Posts: 9
Joined: Fri Jan 20, 2006 1:57 am

Postby onion2k » Fri Jan 20, 2006 10:53 am

ahsanra wrote:I would like you to help me in one another task .. how can i read all the colors that are available in an image (i am only working with PNG, BMP and TIF) and fill them in a drop down box.

First thing to point out is that GD can't do very much with BMP or TIFF images .. so you're going to have to work out a way around that (Imagemagick for example).

ahsanra wrote:Please help me how can i read all the colors present in an image ?

8 bit image:
Syntax: [ Download ] [ Hide ]
<?php



        $image = imagecreatefromgif("heart.gif");



        $colors = array();

        for ($x=0;$x<imagecolorstotal($image);$x++) {

                $rgb = imagecolorsforindex($image,$x);

                $hex = sprintf("%02x%02x%02x",$rgb['red'],$rgb['green'],$rgb['blue']);

                $colors[] = $hex;

        }



        foreach ($colors as $c) {

                echo $c."<br>";

        }



?>


24 bit image:
Syntax: [ Download ] [ Hide ]
<?php



        $image = imagecreatefromjpeg("heart.jpg");

        $width = imagesx($image);

        $height = imagesy($image);



        $colors = array();

        for ($y=0;$y<$height;$y++) {

                for ($x=0;$x<$width;$x++) {

                        $rgb = imagecolorat($image,$x,$y);

                        $r = ($rgb >> 16) & 0xFF;

                        $g = ($rgb >>  & 0xFF;

                        $b = $rgb & 0xFF;

                        $hex = sprintf("%02x%02x%02x",$r,$g,$b);

                        $colors[$hex] += 1;

                }

        }



        foreach ($colors as $c => $count) {

                echo $c." (".$count.")<br>";

        }



?>

If you've uploaded a photographic image then you're going to have a lot of colours .. thousands probably. You can use the $count value to tell how many pixels in the image are set to the specific colour.

I'll leave it up to you to write the code to switch between 8 bit and 24 bit depending on what the PNG file is .. it's very simple if you use imageistruecolor().
User avatar
onion2k
Jedi Mod
 
Posts: 5263
Joined: Tue Dec 21, 2004 6:03 pm
Location: usrlab.com

Postby ahsanra » Sat Jan 21, 2006 12:15 am

Thanks jason again for you kind help.

I have another question for you in the line.

Look at the software below .. i am using the same image in my software and using your provided code it gives me 21 unique colors in the image but if you ll look at the colors given by this software you will see that it only gives only 6 or 7 colors that actually are present in the image.

http://jrm.cc/color-palette-generator/i ... ng&steps=7

I am using a 8 bit PNG image which actually does contain only 7 colors but why using your code i get almost 21 unique and different colors.

List of colors that i got
Syntax: [ Download ] [ Hide ]
<select name="select" size="5"  ><option value="1" style="width:100%; background-color:#1e1612; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#3f540e; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#78c105; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#609309; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#91f001; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#89e003; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#262511; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#68a208; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#36440f; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#81d104; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#4f730b; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#2e350f; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#47630d; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#70b206; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#57820a; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#0000ff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#787576; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#ffff00; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#99cc00; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="1" style="width:100%; background-color:#99ff00; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option></select>


What is the difference in this and my software or this software is giving only websafe colors ?

Thanks in advance
ahsanra
Forum Newbie
 
Posts: 9
Joined: Fri Jan 20, 2006 1:57 am

Postby ahsanra » Thu Jan 26, 2006 12:25 am

Bear in mind that this will do exactly what you're asking for. It will change one specific color to a different one. It you want to change a range of colors (eg all the reds) then you'll need to make the color matching a bit fuzzier.


onion how can i do the fuzzy matching of the colors ... as now i have realised that i need this kind of matching for my software as there are alot alot of variations in colors and i dont need all these variations.
ahsanra
Forum Newbie
 
Posts: 9
Joined: Fri Jan 20, 2006 1:57 am

Postby onion2k » Thu Jan 26, 2006 3:34 pm

I've got a solution .. but .. it's far from perfect. Here's an example:

The original image:
Image

The recoloured image:
Image

I'm sure it's tweakable to get it looking better, but you'll never get it as good as you could do with Photoshop..

Syntax: [ Download ] [ Hide ]
<?php



        $image = imagecreatefrompng("danger.png");

        $width = imagesx($image);

        $height = imagesy($image);



        $colorToChange = "FFFF00";

        $newColor = "0000FF";

        $threshold = 30;



        $c1 = sscanf($colorToChange,"%2x%2x%2x");

        list($h,$s,$v) = rgbtohsv($c1[0],$c1[1],$c1[2]);

        $hueToReplace = $h;

        $c2 = sscanf($newColor,"%2x%2x%2x");

        list($h,$s,$v) = rgbtohsv($c2[0],$c2[1],$c2[2]);

        $newHue = $h;



        for ($y=0;$y<$height;$y++) {

                for ($x=0;$x<$width;$x++) {

                        $rgb = imagecolorat($image,$x,$y);

                        $r = ($rgb >> 16) & 0xFF;

                        $g = ($rgb >>  & 0xFF;

                        $b = $rgb & 0xFF;

                        list($h,$s,$v) = rgbtohsv($r,$g,$b);

                        if (abs($h-$hueToReplace) < $threshold) {

                               

                                list($r,$g,$b) = hsvtorgb($newHue,$s,$v);

                                $color = imagecolorallocate($image,$r,$g,$b);



                                imagesetpixel($image,$x,$y,$color);

                        }

                }

        }

       

        header("Content-Type: image/png");

        imagepng($image);



        //These are PEAR functions from Image_color2 tweaked to suit my coding style.



        function rgbtohsv($r,$g,$b) {

       

        $r = $r / 255;

        $g = $g / 255;

        $b = $b / 255;



        $min = min($r, $g, $b);

        $max = max($r, $g, $b);



        switch ($max) {

                        case 0:

                                $h = $s = $v = 0;

                                break;

                        case $min:

                                $h = $s = 0;

                                $v = $max;

                                break;

                        default:

                                $delta = $max - $min;



                                if( $r == $max ) {

                                        $h = 0 + ( $g - $b ) / $delta;

                                } else if( $g == $max ) {

                                        $h = 2 + ( $b - $r ) / $delta;

                                } else {

                                        $h = 4 + ( $r - $g ) / $delta;

                                }

                                $h *= 60;

                                if($h < 0 ) {

                                        $h += 360;

                                }

                                $s = $delta / $max;

                                $v = $max;

        }

        return array($h, $s, $v);

        }



        function hsvtorgb( $h,$s,$v ) {

       

        if ($s == 0) {

            $r = $g = $b = $v;

        } else {

            $h = $h / 60.0;

            $s = $s;

            $v = $v;



            $hi = floor($h);

            $f = $h - $hi;

            $p = ($v * (1.0 - $s));

            $q = ($v * (1.0 - ($f * $s)));

            $t = ($v * (1.0 - ((1.0 - $f) * $s)));



                        switch( $hi ) {

                                case 0: $r = $v; $g = $t; $b = $p; break;

                                case 1: $r = $q; $g = $v; $b = $p; break;

                                case 2: $r = $p; $g = $v; $b = $t; break;

                                case 3: $r = $p; $g = $q; $b = $v; break;

                                case 4: $r = $t; $g = $p; $b = $v; break;

                                default: $r = $v; $g = $p; $b = $q; break;

                        }

        }

       

        return array(

            (integer) ($r * 255 + 0.5),

            (integer) ($g * 255 + 0.5),

            (integer) ($b * 255 + 0.5)

        );

       

        }



?>
User avatar
onion2k
Jedi Mod
 
Posts: 5263
Joined: Tue Dec 21, 2004 6:03 pm
Location: usrlab.com

Postby John Cartwright » Thu Jan 26, 2006 5:03 pm

ahsanra wrote:Thanks jason again for you kind help.


Whos jason? :roll:
Code: Select all
if ($toBe || $notToBe) echo 'That is the question'; 

NEW HERE?: Please read the Forum Rules, and take the Forum Tour before posting!
User avatar
John Cartwright
Site Admin
 
Posts: 11470
Joined: Tue Dec 23, 2003 3:10 am
Location: Toronto

Postby onion2k » Thu Jan 26, 2006 5:06 pm

Jcart wrote:
ahsanra wrote:Thanks jason again for you kind help.


Whos jason? :roll:

I think he has email notifications switched on, and they come from Jason .. so he assumed that it was someone called Jason who had responded.

Or maybe he's schizophrenic.
User avatar
onion2k
Jedi Mod
 
Posts: 5263
Joined: Tue Dec 21, 2004 6:03 pm
Location: usrlab.com

Postby m3mn0n » Thu Jan 26, 2006 5:15 pm

Honest mistake. :)
User avatar
m3mn0n
PHP Evangelist
 
Posts: 3546
Joined: Tue Aug 13, 2002 3:35 pm
Location: Calgary, Canada

Postby John Cartwright » Thu Jan 26, 2006 5:18 pm

S'all good :) Carry on.
Code: Select all
if ($toBe || $notToBe) echo 'That is the question'; 

NEW HERE?: Please read the Forum Rules, and take the Forum Tour before posting!
User avatar
John Cartwright
Site Admin
 
Posts: 11470
Joined: Tue Dec 23, 2003 3:10 am
Location: Toronto

Postby onion2k » Thu Jan 26, 2006 5:35 pm

This fuzzy color replacement is cool .. I made this:

http://www.phpgd.com/temp/dangertapes_desktop.jpg ( Original resolution MASSIVE image: http://www.phpgd.com/temp/dangertapes.jpg )
User avatar
onion2k
Jedi Mod
 
Posts: 5263
Joined: Tue Dec 21, 2004 6:03 pm
Location: usrlab.com

Postby onion2k » Fri Jan 27, 2006 3:29 pm

Made another one:

http://www.phpgd.com/temp/citroen_desktop.jpg ( Original size: http://www.phpgd.com/temp/citroen.jpg )

The fuzzy matching is improving! Still only doing hue at the moment though. Need to affect the saturation and brightness too.
User avatar
onion2k
Jedi Mod
 
Posts: 5263
Joined: Tue Dec 21, 2004 6:03 pm
Location: usrlab.com

Postby onion2k » Wed Feb 01, 2006 7:30 pm

Getting better still.. there's a bug in the code I posted that messes up hues in the bright red end of the spectrum. Fixed that now. I've also written something to assemble the resulting images into giant poster size color chart things .. it's ace fun.
ImageImage
Those are 1/8th the size of the originals!
User avatar
onion2k
Jedi Mod
 
Posts: 5263
Joined: Tue Dec 21, 2004 6:03 pm
Location: usrlab.com

Next

Return to PHPGD.com

Who is online

Users browsing this forum: bvjklxbho and 2 guests