Jump to content


Photo

Changing colours within photographs


  • Please log in to reply
3 replies to this topic

#1 Kris

Kris
  • Staff Alumni
  • Advanced Member
  • 2,755 posts
  • LocationThe Internet

Posted 05 August 2006 - 11:45 AM

Hi everyone,

I have found the need to be able to change a specific colour within a photograph automatically with PHP (and GD). My progress so far has enabled me to change the hue of a specific colour, but I need to be able to change the saturation and the brightness as well. This is where I appear to be hitting a wall, and I'm struggling to figure it out - Might have something to do with my poor maths skills ;). Hopefully somone could offer me some usefull pointers on how I might go about this. Here is my function so far...
<?php
function recolor($file,$colortochange,$newcolor) {
    $threshold = 30;

    $image = imagecreatefromjpeg($file);
    $width = imagesx($image);
    $height = imagesy($image);

    $c1 = sscanf($colortochange,"%2x%2x%2x");
    list($huetoreplace,$sattoreplace,$valtoreplace) = rgbtohsv($c1[0],$c1[1],$c1[2]);
	
    $c2 = sscanf($newcolor,"%2x%2x%2x");
    list($newhue,$newsat,$newval) = rgbtohsv($c2[0],$c2[1],$c2[2]);

    for($y=0; $y<$height; $y++) {
        for($x=0; $x<$width; $x++) {
            $rgb = imagecolorat($image,$x,$y);
            $a = ($rgb >> 24) & 0xFF;
            $r = ($rgb >> 16) & 0xFF;
            $g = ($rgb >> 8) & 0xFF;
            $b = $rgb & 0xFF;
            list($h,$s,$v) = rgbtohsv($r,$g,$b);

            $angle = ($h >= $huetoreplace) ? 360 - ($h - $huetoreplace) : 360 - ($huetoreplace - $h);
            $angle = ($angle > 180) ? 360 - $angle : $angle;

            if($angle <= $threshold) {
                $h = $newhue + ($h - $huetoreplace);
                if($h < 0) $h += 360;	
                if($h > 360) $h -= 360;
				
/*              $s = $newsat + ($s - $sattoreplace);
                if($s < 0) $s = 0;
                if($s > 100) $s = 100;
				
                $v = $newval + ($v - $valtoreplace);
                if($v < 0) $v = 0;
                if($v > 100) $v = 100;
*/
                list($r,$g,$b) = hsvtorgb($h,$s,$v);
                $color = imagecolorallocatealpha($image,$r,$g,$b,$a);
                imagesetpixel($image,$x,$y,$color);
            }
        }
    }

    header("Content-Type: image/jpeg");
    imagejpeg($image);
}
?>

The above works lovely, replacing the hues where it should. But when I add in the code to alter the saturation and brightness (value), I get some wierd results, such as 'blocks' of colour and random colours here and there. I just can't figure it out.

There are two functions used in the above code that I haven't added, but they are just for converting RGB to HSV and visa-versa. And yes, this function does loop through an image pixel by pixel, if you have any other ideas on how to do this, they would also be appreciated as this method is slow, but it gets the job done (at its current stage).

If anyone needs help understanding my code so far, I can comment it if need be, let me know.

Any help is very much appreciated. :)

#2 onlyican

onlyican
  • Members
  • PipPipPip
  • Advanced Member
  • 921 posts
  • LocationHants - UK

Posted 05 August 2006 - 04:37 PM

You can find the pixel color from an image, and replace it with your color

I have seen one script which replaces all "Non Internet Safe" colors with "Internet Safe" colors, and let me tell ya, it was a good script, but the images came out really really bad
Tell me the problem, I will try tell you the solution

#3 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,021 posts

Posted 05 August 2006 - 06:09 PM

imagecolorset() changes the pallete so one change there affects the whole image
If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#4 Kris

Kris
  • Staff Alumni
  • Advanced Member
  • 2,755 posts
  • LocationThe Internet

Posted 05 August 2006 - 08:44 PM

You can find the pixel color from an image, and replace it with your color

I have seen one script which replaces all "Non Internet Safe" colors with "Internet Safe" colors, and let me tell ya, it was a good script, but the images came out really really bad

I know how to find a pixels colour, my script above demonstrates that ;)

imagecolorset() changes the pallete so one change there affects the whole image

Yeah, that works fine with gifs and 8-bit pngs, but unfortunately I'm working with true colour jpegs. This is why I am using a threshold so that I am replacing a 'range' of slightly different colours with their counterpart replacement colours.

I'm getting closer to solving my problem I think, but still a long way off - I have been tinkering with this on and off for weeks...




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users