PHP 颜色处理

本文最后更新于:2024年3月18日 凌晨

PHP 颜色处理

  • 在颜色支持方面,GD 2.x比GD1.x有了明显的进步,GD 1.x不支持alpha通道,颜色处理也相当简单,并且只支持8位色的图像(最多256种颜色),但创建GD 1.x的8位色图像时,使用的是ImageCreate()函数,并且使用ImageColorAllocate()函数分配的第一个颜色将成为背景色。
  • GD 2.x支持真彩色图像和alpha通道,GD 2.x有一个7位(0-127)的alpha通道。
  • 要创建一个真彩色图像,可使用ImageCreateTrueColor()函数:
1
$image = ImageCreateTrueColor(width,height);
  • 使用ImageColorResolveAlpha()函数创建的颜色索引将包含透明度:
1
$color = ImageColorResolveAlpha(image,red,green,blue,alpha);
  • alpha参数的值介于0(不透明)到127(全透明)之间。
  • 大多数人习惯于8位(0-255)的alpha通道,所以GD采用的7位(0-127)的alpha通道对他们来说也是很容易接受的,每个像素的颜色用一个32位的带正负的整数来表示,它由4个8位字节组成。
  • 对于一个标记了正负的整数,最左边的一位(即最高位),用来指示值的正负,因此只留下31位用于存储真正的信息,PHP的默认整数是一个有正负符号的长整数,我们可以把单个GD调色板项存入其中,整数的正负告诉我们该调色板是否启用抗锯齿功能。
  • 与调色板图像不同的是,GD 2.x创建的真彩色图像的第一种分配颜色并不会自动成为背景色,你可以调用ImageDilledRectangle()函数来使任何你想要的颜色成为背景色。

示例9-12:创建了一个真彩色图像并在其白色背景上绘制了一个半透明的桔红色椭圆。

1
2
3
4
5
6
7
8
9
10
<?php
$im = ImageCreateTrueColor(150, 150);
$white = ImageColorAllocate($im, 255, 255, 255);
ImageAlphaBlending($im, false);
ImageFilledRectangle($im, 0, 0, 150, 150, $white);
$red = ImageColorResolveAlpha($im, 255, 50, 0, 50);
ImageFilledEllipse($im, 75, 75, 80, 63, $red);
header('Content-Type:image/png');
ImagePNG($im);
?>
  • 你可以使用ImageTrueColorToPalette()函数来把真彩色图像转换为带颜色索引图像。

使用alpha通道

  • 在示例9-12中,我们在绘制背景和椭圆之前把alpha合成(blending)功能功能关闭了,alpha合成用于控制在绘图时是否使用alpha通道,如果alpha合成被设置为关闭,则新像素会被原来的旧像素覆盖,如果新像素中存在一个alpha通道,则通道会被保持,但是所有将被覆盖的旧像素的像素信息都会丢失。

示例9-13:alpha合成,在一个橘红色的椭圆上绘制一个带有50%alpha通道的灰色矩形。

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$im = ImageCreateTrueColor(150, 150);
$white = ImageColorAllocate($im, 255, 255, 255);
ImageAlphaBlending($im, false);
ImageFilledRectangle($im, 0, 0, 150, 150, $white);
$red = ImageColorResolveAlpha($im, 255, 50, 0, 63);
ImageFilledEllipse($im, 75, 75, 80, 63, $red);
$gray = ImageColorResolveAlpha($im, 70,70,70,63);
ImageAlphaBlending($im, true);
ImageFilledRectangle($im, 60, 60, 120, 120, $gray);
header('Content-Type:image/png');
ImagePNG($im);
?>

颜色识别

  • 识别图像中某个像素的颜色,可以使用ImageColorAt()函数:
1
$color = ImageColorAt(image,x,y);
  • 对于一个8位的调色板图像,该函数返回一个颜色索引,你可以将返回结果再传递给ImageColorsForIndex()函数,就可以得到实际的RGB值:
1
$values = ImageColorsForIndex(image,index);
  • ImageColorsForIndex()返回的数组包含键名"red”,"green”和"blue”,如果对一个真彩色图像调用ImageColorsForIndex()函数,该函数会多返回一个键名----“alpha”

真彩色的颜色索引

  • ImageColorsResolveAlpha()返回的颜色索引实际上是一个32位的整数,前3个字节为red,green和blue值,接下来的一个字节表示该颜色是否启用抗锯齿功能,剩下的7位保存透明度的值。
  • 例如:
1
$green = ImageColorsResolveAlpha($im,0,0,255,127);
  • 这行代码把$green变量赋值为2130771712,用十六进制表示即0x7F00FF00,二进制形式可表示为01111111000000001111111100000000
  • 下面这行代码等效于上面对于ImageColorsResolveAlpha()函数的调用:
1
$green = 127<<24 | 0<<16 | 255<<8 | 0;
  • 你也可以把两个带0的部分去掉,像这样:
1
$green = 127<<24 | 255<<8
  • 为了析构该值,你可以使用如下代码:
1
2
3
4
$a = ($col & 0x7F000000) >> 24;
$r = ($col & 0x00FF0000) >> 16;
$g = ($col & 0x0FF00000) >> 8;
$b = ($col & 0x000000FF);
  • 实际上我们很少直接像这样操作真色彩的颜色值,一个应用是生成颜色测试图像,显示红,绿,蓝纯色调,例如:
1
2
3
4
5
6
7
8
9
<?php
$im = ImageCreateTrueColor(256,60);
for ($x = 0;$x <256;$x++){
ImageLine($im,$x,0,$x,19,$x);
ImageLine($im,255-$x,20,255-$x,39,$x<<8);
ImageLine($im,$x,40,$x,59,$x<<16);
}
ImagePNG($im);
?>

用文本来显示图像

  • ImageColorAt()有一个很有趣的用处,他可以循环检查图像中的每一个像素的颜色,然后对该颜色数据进行操作,示例9-14为每个像素显示一个#字符,并带有相应的颜色。

示例9-14:把图像转换为文字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>把图像转换为文字</title>
</head>
<body>
<tt>
<?php
$im = imagecreatefrompng('../../../../Media/Photo/image/1.png');
$dy = imagesy($im);
$dx = imagesx($im);
for($y = 0;$y < $dy;$y++) {
for ($x = 0; $x < $dx; $x++) {
$col = imagecolorat($im, $x, $y);
$rgb = imagecolorsforindex($im, $col);
printf('<font color=#%02x%02x%02x>#</font>',$rgb['red'], $rgb['green'], $rgb['blue']);
}
echo "<br/>\n";
}
imagedestroy($im);
?>
</tt>
</body>
</html>

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!