使用 PHP 将特定的 RGB 颜色替换为另一个图像

Posted

技术标签:

【中文标题】使用 PHP 将特定的 RGB 颜色替换为另一个图像【英文标题】:Replace the specific RGB color with another image using PHP 【发布时间】:2016-04-28 21:13:17 【问题描述】:

我从https://***.com/a/32710756/1620626 导出了一个完美的颜色替换脚本。我想用图像背景替换目标颜色。原始图像背景为浅绿色(rgb:0b255b1)。我可以用蓝色替换它,但我不知道如何用图像替换。这是脚本。

这是原图。

一旦我用脚本处理了这张照片。我有这个。

脚本完美地将目标颜色替换为新颜色。现在我想从蓝色变成背景。所以最终的想法是。我选择的背景图片上的这个女孩。

代码如下:

<?php
//https://***.com/a/32710756/1620626
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(0,255,1);//target color
$hueAbsoluteError = 7;//the more the clearer
$replacementColor = RGBtoHSL(0, 192, 239);//new color
/* ---------------------------------------------- */

$filename = 'images/01.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);
?> 

【问题讨论】:

【参考方案1】:

您可以只读取两个图像,源和背景,并从背景图像中获取像素并设置为源。

下面是上面代码的最后一部分,它显示了这个想法:

$filename = 'images/01.png';
$bgFilename = 'images/background.png';
$im = imagecreatefrompng($filename);
$bg = imagecreatefrompng($bgFilename);
$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);
        $bgPixel = imagecolorat($bg, $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]))
            // Instead of taking the replacementColor
            /* $color = HSLtoRGB($replacementColor[0], $replacementColor[1], $colorHSL[2]); */
            /* $red = $color[0]; */
            /* $green= $color[1]; */
            /* $blue = $color[2]; */
            // We just take colors from the backround image pixel
            $red = ($bgPixel >> 16) & 0xFF;
            $green = ($bgPixel >> 8) & 0xFF;
            $blue = $bgPixel & 0xFF;
        

        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);

结果可能如下所示:

【讨论】:

结果看起来不错,但我的服务器上出现错误 500。怎么了? phuket.my/irp @Wilf 您需要检查日志或以其他方式调试它,从 500 错误无法说出问题所在。 Here是我使用的完整代码,下载整个文件夹或克隆存储库,以php convert.php &gt; out.png运行,源图像在images/下。

以上是关于使用 PHP 将特定的 RGB 颜色替换为另一个图像的主要内容,如果未能解决你的问题,请参考以下文章

用ps怎么把一张图片上区域颜色调为另一种颜色?求高手指点!

cvtColor()学习

如何将单个文件中的特定列重复替换为另一个文件的列?

PS将图片某一颜色修改为另一种颜色

将数据框特定列中的 Nan 值替换为另一个数据框特定列中的值

将分割图矢量化为 RGB 颜色