使用 PHP GD 库更改图像的“饱和度”?
Change “Saturation” of an image with PHP GD Library?
有一篇关于如何使用 PHP-GD 库更改图像的 HUE 的 excellent 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));
}
}
}
如果您需要查看辅助函数 rgb2hsl
和 hsl2rgb
的代码,请查看 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
有一篇关于如何使用 PHP-GD 库更改图像的 HUE 的 excellent 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));
}
}
}
如果您需要查看辅助函数 rgb2hsl
和 hsl2rgb
的代码,请查看 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