使用 PHP GD 库更改图像的“饱和度”?

Change “Saturation” of an image with PHP GD Library?

有一篇关于如何使用 PHP-GD 库更改图像的 HUEexcellent answer。但我需要知道如何使用 PHP-GD 更改图像的 SATURATION。这是成功更改图像色调的答案中的代码副本。

function imagehue(&$image, $angle) {
    if($angle % 360 == 0) return;
    $width = imagesx($image);
    $height = imagesy($image);

    for($x = 0; $x < $width; $x++) {
      for($y = 0; $y < $height; $y++) {
        $rgb = imagecolorat($image, $x, $y);
        $r = ($rgb >> 16) & 0xFF;
        $g = ($rgb >> 8) & 0xFF;
        $b = $rgb & 0xFF;            
        $alpha = ($rgb & 0x7F000000) >> 24;
        list($h, $s, $l) = rgb2hsl($r, $g, $b);
        $h += $angle / 360;
        if($h > 1) $h--;
        list($r, $g, $b) = hsl2rgb($h, $s, $l);            
        imagesetpixel($image, $x, $y, imagecolorallocatealpha($image, $r, $g, $b, $alpha));
        }
    }
}

如果您需要查看辅助函数 rgb2hslhsl2rgb 的代码,请查看 original answer。由于 Hue 是 HSL 的参数之一,我想我可以以某种方式修改函数以获得饱和度的工作解决方案。尽管 php 技能有限,但我不得不尝试,但它没有用,并产生了奇怪的结果。这是我正在尝试的修改。


修改后的代码:更新 @mark

建议
function imageSaturation(&$image, $saturationPercentage) {
    $width = imagesx($image);
    $height = imagesy($image);

    for($x = 0; $x < $width; $x++) {
        for($y = 0; $y < $height; $y++) {
            $rgb = imagecolorat($image, $x, $y);
            $r = ($rgb >> 16) & 0xFF;
            $g = ($rgb >> 8) & 0xFF;
            $b = $rgb & 0xFF;            
            $alpha = ($rgb & 0x7F000000) >> 24;
            list($h, $s, $l) = rgb2hsl($r, $g, $b);         
            $s = $s * (100 + $saturationPercentage ) /100;
            if($s > 1) $s = 1;
            list($r, $g, $b) = hsl2rgb($h, $s, $l);            
            imagesetpixel($image, $x, $y, imagecolorallocatealpha($image, $r, $g, $b, $alpha));
        }
    }
}

header('Content-type: image/png');
$image = imagecreatefrompng('rgb.png');
imageSaturation($image, -80);//bring down current image saturation to 80%
imagepng($image);

努力更新: @Dai 向我指出,这些线有助于构建单个 RGB 像素的颜色代码。所以我想这部分可以保持不变吗?

$rgb = imagecolorat($image, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;            
$alpha = ($rgb & 0x7F000000) >> 24;

在下一行中,我们使用 rgb2hsl($r, $g, $b); 简单地将 RGB 值转换为 HSL,并将其分配给 list($h, $s, $l)。我现在卡住的点是这些线。

$s += $saturationPercentage / 100;
if($s > 1) $s--;

我理解语法,但不确定我如何处理这些或者是否需要它们。如果没有答案,有用的提示/建议会很棒。结果,我正在 this image to bring down the saturation from 100% to 80%, but I am getting this image 上尝试代码。

我想你需要像

$s=$s * (100+$saturationPercentage)/100 

否则您只是为每个值添加一个常数,而不是现有值的百分比。

此外,如果新饱和度超过 1,则减 1,可能最好将其设置为 1.0,即像这样完全饱和:

if($s>1)$s=1

否则,假设结果饱和度为 1.3(即非常非常饱和),您会将其变为 0.3,即非常不饱和,而不是 1.0(完全饱和)。

所以,如果 $s 是 0.7,你加上 10%,你会得到

$s = 0.7 * (100 + 10)/100
$s = 0.7 * 1.1
$s = 0.77