Image Color Replacement Technique
Moderators: onion2k, General Moderators
Image Color Replacement Technique
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
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
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:
For a true color image, either jpeg or PNG:
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.
For a GIF or an 8bit PNG you can change the specific color in the palette:
Code: Select all
<?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);
?>
Code: Select all
<?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);
?>
- AKA Panama Jack
- Forum Regular
- Posts: 878
- Joined: Mon Nov 14, 2005 4:21 pm
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
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
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: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.
8 bit image:ahsanra wrote:Please help me how can i read all the colors present in an image ?
Code: Select all
<?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>";
}
?>
Code: Select all
<?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>";
}
?>
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().
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
What is the difference in this and my software or this software is giving only websafe colors ?
Thanks in advance
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
Code: Select all
<select name="select" size="5" ><option value="1" style="width:100%; background-color:#1e1612; "> </option><option value="1" style="width:100%; background-color:#3f540e; "> </option><option value="1" style="width:100%; background-color:#78c105; "> </option><option value="1" style="width:100%; background-color:#609309; "> </option><option value="1" style="width:100%; background-color:#91f001; "> </option><option value="1" style="width:100%; background-color:#89e003; "> </option><option value="1" style="width:100%; background-color:#262511; "> </option><option value="1" style="width:100%; background-color:#68a208; "> </option><option value="1" style="width:100%; background-color:#36440f; "> </option><option value="1" style="width:100%; background-color:#81d104; "> </option><option value="1" style="width:100%; background-color:#4f730b; "> </option><option value="1" style="width:100%; background-color:#2e350f; "> </option><option value="1" style="width:100%; background-color:#47630d; "> </option><option value="1" style="width:100%; background-color:#70b206; "> </option><option value="1" style="width:100%; background-color:#57820a; "> </option><option value="1" style="width:100%; background-color:#000000; "> </option><option value="1" style="width:100%; background-color:#0000ff; "> </option><option value="1" style="width:100%; background-color:#787576; "> </option><option value="1" style="width:100%; background-color:#ffff00; "> </option><option value="1" style="width:100%; background-color:#99cc00; "> </option><option value="1" style="width:100%; background-color:#99ff00; "> </option></select>
Thanks in advance
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.
I've got a solution .. but .. it's far from perfect. Here's an example:
The original image:

The recoloured 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..
The original image:

The recoloured 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..
Code: Select all
<?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)
);
}
?>
- John Cartwright
- Site Admin
- Posts: 11470
- Joined: Tue Dec 23, 2003 2:10 am
- Location: Toronto
- Contact:
- John Cartwright
- Site Admin
- Posts: 11470
- Joined: Tue Dec 23, 2003 2:10 am
- Location: Toronto
- Contact:
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 )
http://www.phpgd.com/temp/dangertapes_desktop.jpg ( Original resolution MASSIVE image: http://www.phpgd.com/temp/dangertapes.jpg )
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.
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.