EDIT 2: Вы, возможно, потребуется оптимизировать что-то и изменить hueAbsoluteError
, чтобы удовлетворить ваши потребности, но оттенок путь к просветлению и резче качество изображения (функции взято с https://gist.github.com/brandonheyer/5254516):
<?php
function RGBtoHSL($r, $g, $b) {
$r /= 255;
$g /= 255;
$b /= 255;
$max = max($r, $g, $b);
$min = min($r, $g, $b);
$l = ($max + $min)/2;
$d = $max - $min;
if($d == 0){
$h = $s = 0;
} else {
$s = $d/(1 - abs(2 * $l - 1));
switch($max){
case $r:
$h = 60 * fmod((($g - $b)/$d), 6);
if ($b > $g) {
$h += 360;
}
break;
case $g:
$h = 60 * (($b - $r)/$d + 2);
break;
case $b:
$h = 60 * (($r - $g)/$d + 4);
break;
}
}
return array(round($h, 2), round($s, 2), round($l, 2));
}
function HSLtoRGB($h, $s, $l){
$c = (1 - abs(2 * $l - 1)) * $s;
$x = $c * (1 - abs(fmod(($h/60), 2) - 1));
$m = $l - ($c/2);
if ($h < 60) {
$r = $c;
$g = $x;
$b = 0;
} else if ($h < 120) {
$r = $x;
$g = $c;
$b = 0;
} else if ($h < 180) {
$r = 0;
$g = $c;
$b = $x;
} else if ($h < 240) {
$r = 0;
$g = $x;
$b = $c;
} else if ($h < 300) {
$r = $x;
$g = 0;
$b = $c;
} else {
$r = $c;
$g = 0;
$b = $x;
}
$r = ($r + $m) * 255;
$g = ($g + $m) * 255;
$b = ($b + $m ) * 255;
return array(floor($r), floor($g), floor($b));
}
/* ---------------CHANGE THESE------------------- */
$colorToReplace = RGBtoHSL(255, 0, 255);
$hueAbsoluteError = 0.4;
$replacementColor = RGBtoHSL(0, 192, 239);
/* ---------------------------------------------- */
$filename = 'img/Mascots_Aviators_General-copy.png';
$im = imagecreatefrompng($filename);
$out = imagecreatetruecolor(imagesx($im), imagesy($im));
$transColor = imagecolorallocatealpha($out, 254, 254, 254, 127);
imagefill($out, 0, 0, $transColor);
for ($x = 0; $x < imagesx($im); $x++) {
for ($y = 0; $y < imagesy($im); $y++) {
$pixel = imagecolorat($im, $x, $y);
$red = ($pixel >> 16) & 0xFF;
$green = ($pixel >> 8) & 0xFF;
$blue = $pixel & 0xFF;
$alpha = ($pixel & 0x7F000000) >> 24;
$colorHSL = RGBtoHSL($red, $green, $blue);
if ((($colorHSL[0] >= $colorToReplace[0] - $hueAbsoluteError) && ($colorToReplace[0] + $hueAbsoluteError) >= $colorHSL[0])){
$color = HSLtoRGB($replacementColor[0], $replacementColor[1], $colorHSL[2]);
$red = $color[0];
$green= $color[1];
$blue = $color[2];
}
if ($alpha == 127) {
imagesetpixel($out, $x, $y, $transColor);
}
else {
imagesetpixel($out, $x, $y, imagecolorallocatealpha($out, $red, $green, $blue, $alpha));
}
}
}
imagecolortransparent($out, $transColor);
imagesavealpha($out, TRUE);
header('Content-type: image/png');
imagepng($out);
EDIT: Лучше решение - определить, если цвет нуждается в замене (с помощью этого метода). Определите оттенок оттенка (я понятия не имею, правильный ли это термин, что я имею в виду - легкость и темнота). Примените его к цвету замены, чтобы придать ему оттенок или ощущение АА.
Итак, как я уже сказал в своем комментарии, вы должны определить, если этот цвет действительно пинг (темный, свет и т.д.). Самое простое решение - применить метод абсолютной ошибки для определенных цветовых каналов. Там может быть (определенно есть) лучше универсальный метод, но я надеюсь, что это будет делать:
$color = [255, 0, 255];
$colorAbsoluteError = [150, 0, 150];
$replacementColor = [0, 192, 239];
$filename = 'img/Mascots_Aviators_General-copy.png';
$im = imagecreatefrompng($filename);
$out = imagecreatetruecolor(imagesx($im), imagesy($im));
$transColor = imagecolorallocatealpha($out, 254, 254, 254, 127);
imagefill($out, 0, 0, $transColor);
for ($x = 0; $x < imagesx($im); $x++) {
for ($y = 0; $y < imagesy($im); $y++) {
$pixel = imagecolorat($im, $x, $y);
$red = ($pixel >> 16) & 0xFF;
$green = ($pixel >> 8) & 0xFF;
$blue = $pixel & 0xFF;
$alpha = ($pixel & 0x7F000000) >> 24;
if ((($red >= $color[0] - $colorAbsoluteError[0]) && ($color[0] + $colorAbsoluteError[0]) >= $red) &&
(($green >= $color[1] - $colorAbsoluteError[1]) && ($color[1] + $colorAbsoluteError[1]) >= $green) &&
(($blue >= $color[2] - $colorAbsoluteError[2]) && ($color[2] + $colorAbsoluteError[2]) >= $blue)){
$red = $replacementColor[0];
$green= $replacementColor[1];
$blue = $replacementColor[2];
}
if ($alpha == 127) {
imagesetpixel($out, $x, $y, $transColor);
}
else {
imagesetpixel($out, $x, $y, imagecolorallocatealpha($out, $red, $green, $blue, $alpha));
}
}
}
imagecolortransparent($out, $transColor);
imagesavealpha($out, TRUE);
header('Content-type: image/png');
imagepng($out);
Это потому, что эти строки не '(255.0.255)' точно. Для этого вам необходимо реализовать цветовой диапазон. – FrogTheFrog
@Helix Да, я пробовал это, держа диапазон ($ red <= 255 && $ red> = 245) && ($ green> = 0 && $ green <= 10) && ($ blue <= 255 && $ blue> = 245), но выход по-прежнему остается таким же. Я прав? –
Дайте мне секунду, и я постараюсь отправить ответ. Возникли проблемы с базовой математикой. – FrogTheFrog