/** JESLI SZUKASZ ROZWIAZANIA UZYJ KODU Z KONCA TEGO POSTU **/
Problem (chyba) rozwiązany.
Godzinę wikipedii później i pisania na stackoverflow mam taki oto kod:
<?php
function showColor($c1, $c2, $c3) {
$hex = rgb2hex($c1,$c2,$c3);
echo '<div style="background-color:#'.$hex.'; height:30px; display:inline;">'.str_repeat(" ", 25).'</div> <b>#'.$hex.'</b> (<b><font color="red">R:</font></b> '.$c1.' | <b><font color="green">G:</font></b> '.$c2.' | <b><font color="blue">B:</font></b> '.$c3.')<br><br>'; }
function rgb2hex($r,$g,$b) {
$colArr=array("r"=>$r,"g"=>$g,"b"=>$b); return (($colArr["r"]<16)?
"0".dechex($colArr["r"]):dechex($colArr["r"])).(($colArr["g"]<16)?
"0".dechex($colArr["g"]):dechex($colArr["g"])).(($colArr["b"]<16)?
"0".dechex($colArr["b"]):dechex($colArr["b"])); }
function rgb2lab($r,$g,$b) {
$eps = 216/24389; $k = 24389/27;
$xr = 0.964221; $yr = 1.0; $zr = 0.825211;
$rgb[0] = $rgb[0]/255;
$rgb[1] = $rgb[1]/255;
$rgb[2] = $rgb[2]/255;
$rgb[0] = ($rgb[0] <= 0.04045)?($rgb[0]/12.92):pow(($rgb[0]+0.055)/1.055,2.4);
$rgb[1] = ($rgb[1] <= 0.04045)?($rgb[1]/12.92):pow(($rgb[1]+0.055)/1.055,2.4);
$rgb[2] = ($rgb[2] <= 0.04045)?($rgb[2]/12.92):pow(($rgb[2]+0.055)/1.055,2.4);
$x = 0.4360747*$rgb[0] + 0.3850649*$rgb[1] + 0.1430804 *$rgb[2];
$y = 0.2225045*$rgb[0] + 0.7168786*$rgb[1] + 0.0606169 *$rgb[2];
$z = 0.0139322*$rgb[0] + 0.0971045*$rgb[1] + 0.7141733 *$rgb[2];
$xr = $x/$xr; $yr = $y/$yr; $zr = $z/$zr;
$fx = ($xr > $eps)?pow($xr, 1/3):($fx = ($k * $xr + 16) / 116);
$fy = ($yr > $eps)?pow($yr, 1/3):($fy = ($k * $yr + 16) / 116);
$fz = ($zr > $eps)?pow($zr, 1/3):($fz = ($k * $zr + 16) / 116);
$lab[] = round(( 116
* $fy ) - 16
); $lab[] = round(500
*($fx-$fy)); $lab[] = round(200
*($fy-$fz)); return $lab;
}
function deltaE($lab1, $lab2) {
$l = 1; $c = 1;
$c1 = sqrt($lab1[1]*$lab1[1]+$lab1[2]*$lab1[2]);
$c2 = sqrt($lab2[1]*$lab2[1]+$lab2[2]*$lab2[2]);
$h1 = (((180000000/M_PI)*atan2($lab1[1],$lab1[2])+360000000)%360000000)/1000000;
$t = (164
<=$h1 AND
$h1<=345
)?
(0
.56
+abs(0
.2
*cos
($h1+168
))):(0
.36
+abs(0
.4
*cos
($h1+35
))); $f = sqrt(pow($c1,4)/(pow($c1,4)+1900));
$sl = ($lab1[0]<16)?(0.511):((0.040975*$lab1[0])/(1+0.01765*$lab1[0]));
$sc = (0.0638*$c1)/(1+0.0131*$c1)+0.638;
$sh = $sc*($f*$t+1-$f);
return sqrt(pow(($lab1[0]-$lab2[0])/($l*$sl),2)+pow(($c1-$c2)/($c*$sc),2)+pow(sqrt(($lab1[1]-$lab2[1])*($lab1[1]-$lab2[1])+($lab1[2]-$lab2[2])*($lab1[2]-$lab2[2])+($c1-$c2)*($c1-$c2))/$sh,2));
}
showColor($c1[0], $c1[1], $c1[2]);
showColor($c2[0], $c2[1], $c2[2]);
$cl1 = rgb2lab($c1[0], $c1[1], $c1[2]);
$cl2 = rgb2lab($c2[0], $c2[1], $c2[2]);
?>
Obliczy różnicę między dwoma kolorami w przestrzeni L A B - inaczej się ponoć tego dobrze nie da zrobić. Teraz tylko spiąć to z kolorami pixeli zdjęć i gotowe.
EditPost jest za dlugi bla bla bla:
http://wklej.org/id/438798/ - poddaje sie
EditOk, udało się porównać kolory, dodanie tego do fotek to już nie problem.
Kod klasy:
<?php
class compareColors {
var $tolerance = 3; //tolerance in %
private function hex2rgb($hex) { //Convert from #FFFFFF to array(0,0,0) in eg.
);
}
private function rgb2cmyk($rgb) { //Simple conversion from RGB namespace to CMYK namespace. (warning! colors can look diff btw rgb and cmyk, its ok for comparing but not for real conversion!)
$K = min(array("r"=>(1
-$rgb[0]), "g"=>(1
-$rgb[1]), "b"=>(1
-$rgb[2
]))); $C = @((1-$rgb[0]-$K)/(1-$K));
$M = @((1-$rgb[1]-$K)/(1-$K));
$Y = @((1-$rgb[2]-$K)/(1-$K));
return(array("C"=>$C, "M"=>$M, "Y"=>$Y, "K"=>$K)); }
function compareCMYKColors($cmyk1, $cmyk2, $returnScale=false) { //Compare 2 CMYK colors with given tolerance, it also can return "tolerane" of matching instead of bool
$tolerance = ($this->tolerance/100); //Convert from % to float
$diff[] = abs($cmyk1["C"]-$cmyk2["C"]); $diff[] = abs($cmyk1["M"]-$cmyk2["M"]); $diff[] = abs($cmyk1["Y"]-$cmyk2["Y"]);
if($returnScale) return ((($max1+$max2)/2)*100); //Convert scale to %
return ($max1["value"]<=$tolerance&&$max2["value"]<=$tolerance) ? true:false;
}
function compareRGBColors($rgb1, $rgb2, $returnScale=false) { //Alias to above but converts from RGB to CMYK first
return $this->compareCMYKColors($this->rgb2cmyk($rgb1), $this->rgb2cmyk($rgb2), $returnScale);
}
function compareHEXColors($hex1, $hex2, $returnScale=false) { //Alias to above
return $this->compareRGBColors($this->hex2rgb($hex1), $this->hex2rgb($hex2), $returnScale);
}
function bathCompare($base, $colors, $format="hex") {
if($format=="hex") { foreach($colors as $color) { if($this->compareHEXColors($base, $color)) $out[] = $color; } return $out; }
if($format=="rgb") { foreach($colors as $color) { if($this->compareRGBColors($base, $color)) $out[] = $color; } return $out; }
if($format=="cmyk") { foreach($colors as $color) { if($this->compareCMYKColors($base, $color)) $out[] = $color; } return $out; }
return false;
}
}
?>
Kod testowy [+ dane testowe]:
http://wklej.org/id/439719/