PHP Developers Network

A community of PHP developers offering assistance, advice, discussion, and friendship.
 
Loading
It is currently Wed Aug 12, 2020 7:34 pm

All times are UTC - 5 hours




Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Fri Jan 20, 2006 2:00 am 
Offline
Forum Newbie

Joined: Fri Jan 20, 2006 1:57 am
Posts: 9
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


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 20, 2006 4:32 am 
Offline
Jedi Mod
User avatar

Joined: Tue Dec 21, 2004 6:03 pm
Posts: 5263
Location: usrlab.com
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.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 20, 2006 4:40 am 
Offline
Forum Regular
User avatar

Joined: Mon Nov 14, 2005 5:21 pm
Posts: 878


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 20, 2006 6:20 am 
Offline
Forum Newbie

Joined: Fri Jan 20, 2006 1:57 am
Posts: 9


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 20, 2006 10:53 am 
Offline
Jedi Mod
User avatar

Joined: Tue Dec 21, 2004 6:03 pm
Posts: 5263
Location: usrlab.com


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 21, 2006 12:15 am 
Offline
Forum Newbie

Joined: Fri Jan 20, 2006 1:57 am
Posts: 9


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 26, 2006 12:25 am 
Offline
Forum Newbie

Joined: Fri Jan 20, 2006 1:57 am
Posts: 9


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 26, 2006 3:34 pm 
Offline
Jedi Mod
User avatar

Joined: Tue Dec 21, 2004 6:03 pm
Posts: 5263
Location: usrlab.com
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)

        );

       

        }



?>


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 26, 2006 5:03 pm 
Offline
Site Admin
User avatar

Joined: Tue Dec 23, 2003 3:10 am
Posts: 11470
Location: Toronto


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 26, 2006 5:06 pm 
Offline
Jedi Mod
User avatar

Joined: Tue Dec 21, 2004 6:03 pm
Posts: 5263
Location: usrlab.com


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 26, 2006 5:15 pm 
Offline
PHP Evangelist
User avatar

Joined: Tue Aug 13, 2002 3:35 pm
Posts: 3547
Location: Calgary, Canada


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 26, 2006 5:18 pm 
Offline
Site Admin
User avatar

Joined: Tue Dec 23, 2003 3:10 am
Posts: 11470
Location: Toronto


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 26, 2006 5:35 pm 
Offline
Jedi Mod
User avatar

Joined: Tue Dec 21, 2004 6:03 pm
Posts: 5263
Location: usrlab.com
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 )


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 27, 2006 3:29 pm 
Offline
Jedi Mod
User avatar

Joined: Tue Dec 21, 2004 6:03 pm
Posts: 5263
Location: usrlab.com


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 01, 2006 7:30 pm 
Offline
Jedi Mod
User avatar

Joined: Tue Dec 21, 2004 6:03 pm
Posts: 5263
Location: usrlab.com
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!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group