注意
<?php
$rgba = imagecolorat($image, $x, $y);
$r = ($rgba >> 16) & 0xFF;
$g = ($rgba >> 8) & 0xFF;
$b = $rgba & 0xFF;
$a = ($rgba & 0x7F000000) >> 24;
?>
仅适用于真彩色图像。对于例如 GIF 图像,这将产生奇怪的结果。对于 GIF 图像,您应始终使用 imagecolorsforindex()。
(PHP 4, PHP 5, PHP 7, PHP 8)
imagecolorsforindex — 获取索引的颜色
返回一个关联数组,其中包含红色、绿色、蓝色和 alpha 键,分别包含指定颜色索引的相应值。
版本 | 描述 |
---|---|
8.0.0 |
image 现在期望一个 GdImage 实例;以前,期望一个有效的 gd resource。 |
8.0.0 |
imagecolorsforindex() 现在如果 color 超出范围,则会抛出 ValueError 异常;以前,会返回 false 。 |
示例 #1 imagecolorsforindex() 示例
<?php
// 打开图像
$im = imagecreatefrompng('nexen.png');
// 获取颜色
$start_x = 40;
$start_y = 50;
$color_index = imagecolorat($im, $start_x, $start_y);
// 使其可读
$color_tran = imagecolorsforindex($im, $color_index);
// 它是什么?
print_r($color_tran);
?>
上面的示例将输出类似于以下内容
Array ( [red] => 226 [green] => 222 [blue] => 252 [alpha] => 0 )
注意
<?php
$rgba = imagecolorat($image, $x, $y);
$r = ($rgba >> 16) & 0xFF;
$g = ($rgba >> 8) & 0xFF;
$b = $rgba & 0xFF;
$a = ($rgba & 0x7F000000) >> 24;
?>
仅适用于真彩色图像。对于例如 GIF 图像,这将产生奇怪的结果。对于 GIF 图像,您应始终使用 imagecolorsforindex()。
如果您想更改特定颜色的强度或亮度级别,则需要将颜色格式从 RGB 转换为 HSL。
以下函数将 RGB 数组 (red, green, blue) 转换为 HSL 数组 (hue, saturation, lightness)
<?php
/**
* 将 RGB 颜色数组转换为 HSL 数组
*
* @param array $ RGB 颜色集
* @return array HSL 集
*/
function rgb2hsl($rgb){
$clrR = ($rgb[0] / 255);
$clrG = ($rgb[1] / 255);
$clrB = ($rgb[2] / 255);
$clrMin = min($clrR, $clrG, $clrB);
$clrMax = max($clrR, $clrG, $clrB);
$deltaMax = $clrMax - $clrMin;
$L = ($clrMax + $clrMin) / 2;
if (0 == $deltaMax){
$H = 0;
$S = 0;
}
else{
if (0.5 > $L){
$S = $deltaMax / ($clrMax + $clrMin);
}
else{
$S = $deltaMax / (2 - $clrMax - $clrMin);
}
$deltaR = ((($clrMax - $clrR) / 6) + ($deltaMax / 2)) / $deltaMax;
$deltaG = ((($clrMax - $clrG) / 6) + ($deltaMax / 2)) / $deltaMax;
$deltaB = ((($clrMax - $clrB) / 6) + ($deltaMax / 2)) / $deltaMax;
if ($clrR == $clrMax){
$H = $deltaB - $deltaG;
}
else if ($clrG == $clrMax){
$H = (1 / 3) + $deltaR - $deltaB;
}
else if ($clrB == $clrMax){
$H = (2 / 3) + $deltaG - $deltaR;
}
if (0 > $H) $H += 1;
if (1 < $H) $H -= 1;
}
return array($H, $S, $L);
}
?>
使用 `imagecolorsforindex` 获取像素的 alpha 透明度非常直观和简单,例如:
<?php
$rgba = imagecolorsforindex($image, imagecolorat($image, $x, $y));
$alpha = $rgba["alpha"];
?>
但是,如果需要处理图像的每个像素,则应该使用 `imagecolorat` 命令的返回值来获取 alpha 透明度,因为它速度更快,而且性能提升很大。
<?php
$rgba = imagecolorat($image, $x, $y);
$alpha = ($rgba & 0x7F000000) >> 24;
?>
我对来自 slepichev 的 rgb2hsl 函数进行了一些优化,使其更短,也希望更快。
<?php
/**
* 将 RGB 颜色数组转换为 HSL 数组
*
* @param array $ RGB 颜色集,每个颜色分量范围为 0 到 255
* @return array HSL 集,每个颜色分量范围为 0 到 1
*/
function rgb2hsl($rgb){
$clrR = ($rgb[0]);
$clrG = ($rgb[1]);
$clrB = ($rgb[2]);
$clrMin = min($clrR, $clrG, $clrB);
$clrMax = max($clrR, $clrG, $clrB);
$deltaMax = $clrMax - $clrMin;
$L = ($clrMax + $clrMin) / 510;
if (0 == $deltaMax){
$H = 0;
$S = 0;
}
else{
if (0.5 > $L){
$S = $deltaMax / ($clrMax + $clrMin);
}
else{
$S = $deltaMax / (510 - $clrMax - $clrMin);
}
if ($clrMax == $clrR) {
$H = ($clrG - $clrB) / (6.0 * $deltaMax);
}
else if ($clrMax == $clrG) {
$H = 1/3 + ($clrB - $clrR) / (6.0 * $deltaMax);
}
else {
$H = 2 / 3 + ($clrR - $clrG) / (6.0 * $deltaMax);
}
if (0 > $H) $H += 1;
if (1 < $H) $H -= 1;
}
return array($H, $S,$L);
}
?>
之前微软的 sepia 示例似乎有一个系数导致图像偏粉红。以下是一个修改后的示例,它使用的是纯粹的微软 sepia(根据维基百科上的 sepia 条目)。
<?
function imagetosepia(&$img) {
if (!($t = imagecolorstotal($img))) {
$t = 256;
imagetruecolortopalette($img, true, $t);
}
$total = imagecolorstotal( $img );
for ( $i = 0; $i < $total; $i++ ) {
$index = imagecolorsforindex( $img, $i );
$red = ( $index["red"] * 0.393 + $index["green"] * 0.769 + $index["blue"] * 0.189 );
$green = ( $index["red"] * 0.349 + $index["green"] * 0.686 + $index["blue"] * 0.168 );
$blue = ( $index["red"] * 0.272 + $index["green"] * 0.534 + $index["blue"] * 0.131 );
if ($red > 255) { $red = 255; }
if ($green > 255) { $green = 255; }
if ($blue > 255) { $blue = 255; }
imagecolorset( $img, $i, $red, $green, $blue );
}
}
?>
这是一个使用微软定义的 sepia 滤镜。
<?php
function imagesepia( $img ) {
$total = imagecolorstotal( $img );
for ( $i = 0; $i < $total; $i++ ) {
$index = imagecolorsforindex( $img, $i );
$red = ( $index["red"] * 0.393 + $index["green"] * 0.769 + $index["blue"] * 0.189 ) / 1.351;
$green = ( $index["red"] * 0.349 + $index["green"] * 0.686 + $index["blue"] * 0.168 ) / 1.203;
$blue = ( $index["red"] * 0.272 + $index["green"] * 0.534 + $index["blue"] * 0.131 ) / 2.140;
imagecolorset( $img, $i, $red, $green, $blue );
}
}
?>
更正 abasoft dot it 上的 m4551 例子
ImageTrueColorToPalette($im,1,$t);
可能会产生比 $t 更少的颜色,因此为了确保,for 循环应该调用 “$i<ImageColorsTotal($im)” 而不是 “$i<$t”,否则您会收到警告:颜色索引 [0-9] 超出范围
关于 m4551 的转换方法——实际的 CCIR 批准的 RGB 到灰度转换如下
灰度分量 = 0.2125*R + 0.7154*G + 0.0721*B
(参见现代显示器的 CCIR 建议 709)
这是一个将图像转换为灰度(即使是从真彩色源(jpeg 或 png))的函数。
质量略差,但速度很快...
function imagegreyscale(&$img, $dither=1) {
if (!($t = imagecolorstotal($img))) {
$t = 256;
imagetruecolortopalette($img, $dither, $t);
}
for ($c = 0; $c < $t; $c++) {
$col = imagecolorsforindex($img, $c);
$min = min($col['red'],$col['green'],$col['blue']);
$max = max($col['red'],$col['green'],$col['blue']);
$i = ($max+$min)/2;
imagecolorset($img, $c, $i, $i, $i);
}
}
这是一个更好的灰度、棕褐色和通用着色函数。此函数更好,因为
1) 与真彩色图像一起使用(其他棕褐色代码没有)。
2) 提供更好的灰度转换(是的,我说的是“更好”。其他灰度代码使用 imagetruecolortopalette,它不适用于灰度转换。
3) 其他棕褐色代码真的很鲜艳,对我的口味来说有点过头。此函数允许您选择性地将灰度的着色设置为任何您想要的颜色。
4) 单个函数用于灰度、棕褐色和任何其他您能想到的着色。
以下是一些示例
imagegrayscaletint ($img); // 灰度,无着色
imagegrayscaletint ($img,304,242,209); // 我用于棕褐色的方法
imagegrayscaletint ($img,0,0,255); // 一个浆果蓝的图像
着色的 RGB 值通常在 0 到 255 之间。但是,您可以使用大于 255 的值来提亮和“烧毁”图像。上面的棕褐色示例稍微做到了这一点,下面的示例更好地说明了如何提亮图像并稍微烧毁亮区
imagegrayscaletint ($img,400,400,400); // 提亮图像
imagegrayscaletint ($img,127,127,127); // 使图像变暗
<?
function imagegrayscaletint (&$img, $tint_r = 255, $tint_g = 255, $tint_b = 255) {
$width = imagesx($img); $height = imagesy($img);
$dest = imagecreate ($width, $height);
for ($i=0; $i<256; $i++) imagecolorallocate ($dest, $i, $i, $i);
imagecopyresized ($dest, $img, 0, 0, 0, 0, $width, $height, $width, $height);
for ($i = 0; $i < 256; $i++) imagecolorset ($dest, $i, min($i * abs($tint_r) / 255, 255), min($i * abs($tint_g) / 255, 255), min($i * abs($tint_b) / 255, 255));
$img = imagecreate ($width, $height);
imagecopy ($img, $dest, 0, 0, 0, 0, $width, $height);
imagedestroy ($dest);
}
?>