【问题标题】:Change “Saturation” of an image with PHP GD Library?使用 PHP GD 库更改图像的“饱和度”?
【发布时间】:2016-01-05 05:34:59
【问题描述】:

excellent answer 介绍了如何使用 PHP-GD 库更改图像的 HUE。但我需要知道如何使用 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;

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

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

我了解语法,但不确定我如何处理这些,或者是否需要它们。如果不是答案,有用的提示/建议会很棒。我正在尝试 this image 上的代码将饱和度从 100% 降低到 80%,但结果是 this image

【问题讨论】:

  • 您发布的最后一段代码有什么问题(“我真的迷路了”)。没有执行任何计算,只是进行位移和位晒以提取表示每个像素颜色分量(红色、绿色、蓝色和不透明度)的字节 (0-255) 值。
  • @Dai TBH,我第一次遇到这些二进制概念,真的不明白他们在做什么。我绝对应该研究这些,但现在真的买不起。请查看更新的问题。你的意思是说它们应该保持不变?

标签: php image image-processing gd gdlib


【解决方案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

【讨论】:

  • with imageSaturation($image, 80); 实际上,我希望将饱和度从 100% 降低到 80%。我还有哪里错了?
  • 所以你可以通过-20,或者把你的代码改成$s *= $saturationPercentage/100
  • 我现在看到了问题 - 您的图像是托盘化的,而不是真彩色。在加载图像后尝试调用imagepalettetotruecolor($image) 作为快速修复。如需适当的解决方案,请查看此处php.net/manual/en/function.imagepalettetotruecolor.php。基本上,当您进行位移以获得$r$g$b 时,您将获得$r$g 以及调色板中$b 的索引而不是您的索引期待。
  • 这 100% 有效。感谢您的时间。请看最后一次修改代码的FINAL update,里面包含了你所有的建议,如果还有错误请指出。这是我的理解。如果我需要对图像完全去饱和,我可以调用 -100,我认为调用任何超过 100 的值都是没有意义的。有什么建议吗?
  • 很高兴它成功了!我又看了看,我认为你现在几乎“正确”了。添加饱和度是完全合理的 - 有时人们想添加一些 pop 来褪色的图片。
猜你喜欢
  • 2010-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-05
  • 1970-01-01
相关资源
最近更新 更多