Jump to content

Archived

This topic is now archived and is closed to further replies.

Kris

Changing colours within photographs

Recommended Posts

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 [i]hue[/i] of a specific colour, but I need to be able to change the [i]saturation[/i] and the [i]brightness[/i] 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...
[code]<?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);
}
?>[/code]

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. :)

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
imagecolorset() changes the pallete so one change there affects the whole image

Share this post


Link to post
Share on other sites
[quote author=onlyican link=topic=103079.msg410263#msg410263 date=1154795844]
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
[/quote]I know how to find a pixels colour, my script above demonstrates that ;)

[quote author=Barand link=topic=103079.msg410301#msg410301 date=1154801369]
imagecolorset() changes the pallete so one change there affects the whole image
[/quote]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...

Share this post


Link to post
Share on other sites

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.