Да, я знаю, что есть вопросы, связанные с stackoverflow, но они не очень хорошо работают по моей потребности. Я пытаюсь заменить цвет изображения другим цветом. В нижеприведенном коде я заменяю (255,0,255) на (0,192,239). Ниже код работает, но не полностью заменяет новый цвет над розовым (255,0,255) цвета, некоторые мелкие точки или граница розового цвета все еще остаются, как вы можете видеть на выходном изображении.
Как я могу получить его идеальное решение?
<?php $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 == 255 && $green == 0 && $blue == 255) { $red = 0; $green=192; $blue =239; } 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 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);