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

时间:2015-10-07 20:06:35

标签: php image image-processing gd gdlib

如何使用PHP-GD库更改图像的 HUE excellent answer。但我需要知道如何使用PHP-GD更改图像的 SATURATION 。以下是答案中代码的副本,该答案成功更改了图像的HUE。

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技能有限,但我不得不尝试,但它不起作用并产生奇怪的结果。这是我正在尝试的修改。

修改后的代码:@ strong

建议更新
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;

在下一行中,我们只是将RGB值转换为HSL rgb2hsl($r, $g, $b);并将其分配给list($h, $s, $l)。我此刻陷入困境的是这些界限。

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

我理解语法,但不确定我是如何处理它们的,或者它们是否甚至是必需的。如果没有答案有用的提示/建议将是伟大的。我正在尝试使用this image上的代码将饱和度从100%降低到80%,但结果是this image

1 个答案:

答案 0 :(得分:1)

我认为你需要像

这样的东西
$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