PHP 8.3.4 Released!

imagecolorallocate

(PHP 4, PHP 5, PHP 7, PHP 8)

imagecolorallocate为图像分配颜色

说明

imagecolorallocate(
    GdImage $image,
    int $red,
    int $green,
    int $blue
): int|false

返回颜色标识符,表示由指定 RGB 成分组成的颜色。

必须调用 imagecolorallocate() 创建要在 image 表示的图像中使用的每种颜色。

注意:

第一次调用 imagecolorallocate() 会对基于调色板的图像填充背景色——使用 imagecreate() 建立的图像。

参数

image

由图象创建函数(例如imagecreatetruecolor())返回的 GdImage 对象。

red

红色成分的值。

green

绿色成分的值。

blue

蓝色成分的值。

这些参数是 0 到 255 之间的整数或者 0x00 到 0xFF 之间的十六进制数字。

返回值

颜色标识符,如果分配失败,则为 false

警告

此函数可能返回布尔值 false,但也可能返回等同于 false 的非布尔值。请阅读 布尔类型章节以获取更多信息。应使用 === 运算符来测试此函数的返回值。

更新日志

版本 说明
8.0.0 image 现在需要 GdImage 实例;之前需要有效的 gd resource

示例

示例 #1 imagecolorallocate() 示例

<?php

$im
= imagecreate(100, 100);

// 设置背景为红色
$background = imagecolorallocate($im, 255, 0, 0);

// 设置一些颜色
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im, 0, 0, 0);

// 十六进制方式
$white = imagecolorallocate($im, 0xFF, 0xFF, 0xFF);
$black = imagecolorallocate($im, 0x00, 0x00, 0x00);

?>

参见

add a note

User Contributed Notes 21 notes

up
22
jahservant 13 at gmail dot com
14 years ago
Note that you can only assign 255 colors to any image palette. If you try assigning more, imagecolorallocate() will fail.

If, for example, you are randomly allocating colors, it will be wise to check if you have used up all of the colors possible. You can use imagecolorclosest() to get the closest assigned color:
<?php
//assign random rgb values
$c1 = mt_rand(50,200); //r(ed)
$c2 = mt_rand(50,200); //g(reen)
$c3 = mt_rand(50,200); //b(lue)
//test if we have used up palette
if(imagecolorstotal($pic)>=255) {
//palette used up; pick closest assigned color
$color = imagecolorclosest($pic, $c1, $c2, $c3);
} else {
//palette NOT used up; assign new color
$color = imagecolorallocate($pic, $c1, $c2, $c3);
}
?>

Also, imagecolorallocate() will assign a new color EVERY time the function is called, even if the color already exists in the palette:
<?php
// [...]
imagecolorallocate($pic,125,125,125); //returns 5
imagecolorallocate($pic,125,125,125); //returns 6
imagecolorallocate($pic,125,125,125); //returns 7
// [...]
imagecolorallocate($pic,125,125,125); //returns 23
imagecolorallocate($pic,125,125,125); //returns 25
// [...]
// etc...
?>

So here, imagecolorexact() is useful:
<?php
//see if color already exists
$color = imagecolorexact($pic, $c1, $c2, $c3);
if(
$color==-1) {
//color does not exist; allocate a new one
$color = imagecolorallocate($pic, $c1, $c2, $c3);
}
?>

And, for nerdy-ness sake, we can put the two ideas together:
<?php
//assign random rgb values
$c1 = mt_rand(50,200); //r(ed)
$c2 = mt_rand(50,200); //g(reen)
$c3 = mt_rand(50,200); //b(lue)
//get color from palette
$color = imagecolorexact($pic, $c1, $c2, $c3);
if(
$color==-1) {
//color does not exist...
//test if we have used up palette
if(imagecolorstotal($pic)>=255) {
//palette used up; pick closest assigned color
$color = imagecolorclosest($pic, $c1, $c2, $c3);
} else {
//palette NOT used up; assign new color
$color = imagecolorallocate($pic, $c1, $c2, $c3);
}
}
?>

Or as a function:
<?php
function createcolor($pic,$c1,$c2,$c3) {
//get color from palette
$color = imagecolorexact($pic, $c1, $c2, $c3);
if(
$color==-1) {
//color does not exist...
//test if we have used up palette
if(imagecolorstotal($pic)>=255) {
//palette used up; pick closest assigned color
$color = imagecolorclosest($pic, $c1, $c2, $c3);
} else {
//palette NOT used up; assign new color
$color = imagecolorallocate($pic, $c1, $c2, $c3);
}
}
return
$color;
}

for(
$i=0; $i<1000; $i++) { //1000 because it is significantly greater than 255
//assign random rgb values
$c1 = mt_rand(50,200); //r(ed)
$c2 = mt_rand(50,200); //g(reen)
$c3 = mt_rand(50,200); //b(lue)
//generate the color
$color = createcolor($pic,$c1,$c2,$c3);
//do something with color...
}
?>
up
9
Ludo
16 years ago
When working on an existant GIF images, if the number of different colours has reached the limits of the GIF format, imagecolorallocate will not use to the colour you ask her within the parameters, she will apply black !

That's a problem when generating images "on-the-fly" with many manipulations, from a GIF image.
To go round the problem, you have to convert the GIF image into a PNG one, and then you can work on the PNG and everything will be ok.

For example :
<?php
// first, convert into a PNG image
$handle = imagecreatefromgif('my_image.gif');
imagepng($handle, 'my_image.png');
imagedestroy($handle);

// then, you can work on it
$handle = imagecreatefrompng('my_image.png');
/*
* work on the image
*/
imagegif($handle);
?>
up
4
William Barath
16 years ago
Lots of hsv2rgb commentary but no working example, so here's mine:

<?php // hsv2rgb example translated from ImageMagick C code
function hsv2rgb($h, $s, $v)
{
$s /= 256.0;
if (
$s == 0.0) return array($v,$v,$v);
$h /= (256.0 / 6.0);
$i = floor($h);
$f = $h - $i;
$p = (integer)($v * (1.0 - $s));
$q = (integer)($v * (1.0 - $s * $f));
$t = (integer)($v * (1.0 - $s * (1.0 - $f)));
switch(
$i) {
case
0: return array($v,$t,$p);
case
1: return array($q,$v,$p);
case
2: return array($p,$v,$t);
case
3: return array($p,$q,$v);
case
4: return array($t,$p,$v);
default: return array(
$v,$p,$q);
}
}

$image = ImageCreateTrueColor(256,128);
for (
$y=0; $y<64; $y++) for($x=0; $x<256; $x++){
list(
$r,$g,$b) = hsv2rgb($x | 7,255,($y*4) |7);
$color = ($r << 16 ) | ($g << 8) | $b;
imagesetpixel($image, $x, $y-4, $color);
}
for (
$y=64; $y<128; $y++) for($x=0; $x<256; $x++){
list(
$r,$g,$b) = hsv2rgb($x|7,((127-$y)*4)|7,255);
$color = ($r << 16) | ($g << 8) | $b;
imagesetpixel($image, $x, $y-4, $color);
}
for (
$y=120; $y<128; $y++) for($x=0; $x<256; $x++){
$color = (($x |7) << 16) | (($x |7) << 8) | ($x |7);
imagesetpixel($image, $x, $y, $color);
}
header("Content-Type: image/png");
imagepng($image);
?>
up
3
jernberg at fairytale dot se
20 years ago
this might help someone, how to allocate an color from an html color-definition:

<?php
$fg
= "#ff0080";

$red = 100;
$green = 100;
$blue = 100;
if(
eregi( "[#]?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})", $fg, $ret ) )
{
$red = hexdec( $ret[1] );
$green = hexdec( $ret[2] );
$blue = hexdec( $ret[3] );
}

$text_color = ImageColorAllocate( $img1, $red, $green, $blue );
?>
up
1
andreoli dot carlo at libero dot it
18 years ago
hsl to RGB
(not yet optimized but it function)

<?php
function hslToRgb ($h, $s, $l) {
if (
$h>240 || $h<0) return array(0,0,0);
if (
$s>240 || $s<0) return array(0,0,0);
if (
$l>240 || $l<0) return array(0,0,0);
if (
$h<=40) {
$R=255;
$G=(int)($h/40*256);
$B=0;
}
elseif (
$h>40 && $h<=80) {
$R=(1-($h-40)/40)*256;
$G=255;
$B=0;
}
elseif (
$h>80 && $h<=120) {
$R=0;
$G=255;
$B=($h-80)/40*256;
}
elseif (
$h>120 && $h<=160) {
$R=0;
$G=(1-($h-120)/40)*256;
$B=255;
}
elseif (
$h>160 && $h<=200) {
$R=($h-160)/40*256;
$G=0;
$B=255;
}
elseif (
$h>200) {
$R=255;
$G=0;
$B=(1-($h-200)/40)*256;
}
$R=$R+(240-$s)/240*(128-$R);
$G=$G+(240-$s)/240*(128-$G);
$B=$B+(240-$s)/240*(128-$B);
if (
$l<120) {
$R=($R/120)*$l;
$G=($G/120)*$l;
$B=($B/120)*$l;
}
else {
$R=$l*((256-$R)/120)+2*$R-256;
$G=$l*((256-$G)/120)+2*$G-256;
$B=$l*((256-$B)/120)+2*$B-256;
}
if (
$R<0) $R=0;
if (
$R>255) $R=255;
if (
$G<0) $G=0;
if (
$G>255) $G=255;
if (
$B<0) $B=0;
if (
$B>255) $B=255;

return array((int)
$R,(int)$G,(int)$B);
}
?>
up
1
smoli at paranoya dot ch
19 years ago
Some of you maybe want to use HSV color model for drawing color selectors and circles:

<?php
function &colormap_hsv_to_rgb($h, $s, $v)
{
$ret = new stdClass();

if(
$s == 0)
{
$ret->r = $v;
$ret->g = $v;
$ret->b = $v;

return
$ret;
}
else
{
$h = floatval($h) / 255.0;
$s = floatval($s) / 255.0;
$v = floatval($v) / 255.0;

$hue = $h;

if(
$hue == 1.0)
$hue = 0.0;

$hue *= 6.0;

$i = intval($hue);
$f = $hue - floatval($i);
$w = $v * (1.0 - $s);
$q = $v * (1.0 - ($s * $f));
$t = $v * (1.0 - ($s * (1.0 - $f)));

switch(
$i)
{
case
0: $ret->r = $v; $ret->g = $t; $ret->b = $w; break;
case
1: $ret->r = $q; $ret->g = $v; $ret->b = $w; break;
case
2: $ret->r = $w; $ret->g = $v; $ret->b = $t; break;
case
3: $ret->r = $w; $ret->g = $q; $ret->b = $v; break;
case
4: $ret->r = $t; $ret->g = $w; $ret->b = $v; break;
case
5: $ret->r = $v; $ret->g = $w; $ret->b = $q; break;
}
}

$ret->r = intval($ret->r * 255.0);
$ret->g = intval($ret->g * 255.0);
$ret->b = intval($ret->b * 255.0);

return
$ret;
}
?>
up
3
SW
18 years ago
This works! A Black-Image with vertical centered white Aliased Arial-Text and same left and right margin - used for Menu-Buttons.

<?php

function createImgText ($string="", $fontsize=0, $marginX=0, $imgH=0 , $fontfile="", $imgColorHex="", $txtColorHex=""){
if(
$string!=""){
Header("Content-type: image/png");
//
$spacing = 0;
$line = array("linespacing" => $spacing);
$box = @imageftbbox($fontsize,0,$fontfile,$string,$line)
or die(
"ERROR");
$tw=$box[4]-$box[0]; //image width
$marginY = $imgH - (($imgH - $fontsize) / 2);
$imgWidth = $tw + (2*$marginX);
$im = ImageCreate($imgWidth, $imgH);
$int = hexdec($imgColorHex);
$arr = array("red" => 0xFF & ($int >> 0x10),
"green" => 0xFF & ($int >> 0x8),
"blue" => 0xFF & $int);
$black = ImageColorAllocate($im, $arr["red"], $arr["green"], $arr["blue"]);
$int = hexdec($txtColorHex);
$arr = array("red" => 0xFF & ($int >> 0x10),
"green" => 0xFF & ($int >> 0x8),
"blue" => 0xFF & $int);
$white = ImageColorAllocate($im, $arr["red"], $arr["green"], $arr["blue"]);
ImageFtText($im, $fontsize, 0, $marginX, $marginY, $white, $fontfile, $string, array());
ImagePng($im);
ImageDestroy($im);
}else{
echo
"ERROR!";
}
}
createImgText ("Hello World", 9, 10, 18, "arial.ttf", "000000", "FFFFFF");
?>
up
1
picklecj at rose-hulman dot edu
16 years ago
Another solution to color limitation issues when creating gradients. This file takes width (px) and left and right colors (hex) and makes a gradient while only allocating 250 colors.

<?php
$leftR
= hexdec(substr($_GET["left"],0,2));
$leftG = hexdec(substr($_GET["left"],2,2));
$leftB = hexdec(substr($_GET["left"],4,2));
$rightR = hexdec(substr($_GET["right"],0,2));
$rightG = hexdec(substr($_GET["right"],2,2));
$rightB = hexdec(substr($_GET["right"],4,2));
$image=imagecreate($_GET["width"],1);
for(
$i=0;$i<250;$i++) {
$colorset[$i] = imagecolorallocate($image, $leftR + ($i*(($rightR-$leftR)/250)), $leftG + ($i*(($rightG-$leftG)/250)), $leftB + ($i*(($rightB-$leftB)/250)));
}
for(
$i=0;$i<($_GET["width"]);$i++) {
imagesetpixel ($image, $i, 0, $colorset[(int)($i/($_GET["width"]/250))] );
}
header("Content-type: image/png");
imagepng($image);
imagedestroy($image);
?>

example: gradient.php?width=640&left=000000&right=FF0000

Makes a 640px-wide image that fades from black to red.
up
1
tyberis
19 years ago
2 functions to convert from HSV colorspace (hue/saturation/brightness) to RGB (red/green/blue) colorspace and back.
<?php
// $c = array($red, $green, $blue)
// $red=[0..1], $green=[0..1], $blue=[0..1];
function rgb2hsv($c) {
list(
$r,$g,$b)=$c;
$v=max($r,$g,$b);
$t=min($r,$g,$b);
$s=($v==0)?0:($v-$t)/$v;
if (
$s==0)
$h=-1;
else {
$a=$v-$t;
$cr=($v-$r)/$a;
$cg=($v-$g)/$a;
$cb=($v-$b)/$a;
$h=($r==$v)?$cb-$cg:(($g==$v)?2+$cr-$cb:(($b==$v)?$h=4+$cg-$cr:0));
$h=60*$h;
$h=($h<0)?$h+360:$h;
}
return array(
$h,$s,$v);
}

// $c = array($hue, $saturation, $brightness)
// $hue=[0..360], $saturation=[0..1], $brightness=[0..1]
function hsv2rgb($c) {
list(
$h,$s,$v)=$c;
if (
$s==0)
return array(
$v,$v,$v);
else {
$h=($h%=360)/60;
$i=floor($h);
$f=$h-$i;
$q[0]=$q[1]=$v*(1-$s);
$q[2]=$v*(1-$s*(1-$f));
$q[3]=$q[4]=$v;
$q[5]=$v*(1-$s*$f);
//return(array($q[($i+4)%5],$q[($i+2)%5],$q[$i%5]));
return(array($q[($i+4)%6],$q[($i+2)%6],$q[$i%6])); //[1]
}
}
?>

[1] - EDITOR NOTE: THIS IS A FIX FROM "hc at hob(removethis)soft dot net".
up
1
chris at drunkenpirates dot co dot uk
20 years ago
<?php

/*
An example combining the use of ImageColorAllocate, Imagesetpixel, Imagecopyresized and some basic Trig
*/

Header("Content-type: image/png");

$height = 128;
$width = 128;

$imA = ImageCreate($width, $height);
$imB = ImageCreate($width*4, $height*4);
$bckA = ImageColorAllocate($imA, 0,0,0);
$bckB = ImageColorAllocate($imB, 0,0,0);

//GENERATE GRAY SCALE PALLETE

for($c=0;$c<256;$c++){
ImageColorAllocate($imA, $c, $c, $c);
}

//PRODUCE DATA

$m=rand(0,10);
for(
$c=0;$c<128;$c++){
$s= (sin( deg2rad($c*360*$m/128) )+1)*127;
$col_arr[$c]=$s;
}
for(
$y=0;$y<$height;$y++){
for(
$x=0;$x<$width;$x++){
$imgA[$x][$y]=$col_arr[$x];
}
}
for(
$y=0;$y<$height;$y++){
for(
$x=0;$x<$width;$x++){
$imgB[$x][$y]=$col_arr[$y];
}
}

//SET PIXELS

for($y=0;$y<$height;$y++){
for(
$x=0;$x<$width;$x++){
$imgC[$x][$y]=$imgA[$x][$y]+$imgB[$x][$y];
$s=$imgC[$x][$y]/2;
Imagesetpixel($imA,$x,$y,$s);
}
}

//RESIZE IMAGE FOR DISPLAY

Imagecopyresized ($imB, $imA, 0, 0, 0, 0, $width*4, $height*4, $width, $width);
ImagePNG($imB);
?>
up
1
bisqwit at iki dot fi
22 years ago
Actually, you can't allocate more than 256 colours for an paletted image (ImageCreate).
Use ImageCreateTrueColor instead. For it to work, you need libgd version 2 support in php though.
up
1
behun at webconsult dot sk
17 years ago
Also, when you need more then 256 colors, use imagecreatetruecolor function. With this function you can use unlimited number of colors.
up
1
aaron at parecki dot com
19 years ago
This will let you tint an image to any specific color. The blacks of the source image become your specified color, and the whites remain white. Works best for colorizing greyscale images.

<?php

$r
= 224;
$g = 192;
$b = 0;
$source_file = "picture.jpg";

$im_src = ImageCreateFromJpeg($source_file);
$im_tint = ImageCreate(imagesx($im_src),imagesy($im_src));
for (
$c = 0; $c < 255; $c++) {
ImageColorAllocate($im_tint, max($r,$c), max($g,$c), max($b,$c));
}
ImageCopyMerge($im_tint,$im_src,0,0,0,0, imagesx($im_src), imagesy($im_src), 100);
ImageDestroy($im_src);

header("Content-type: image/jpeg");
imagejpeg($im_tint);

?>
up
1
phillip dot gooch at gmail dot com
13 years ago
If you even in a situation where it's not allocating the color you want it could be because of your images color allocation table. GIF and 8-bit PNG images are very susceptible to this.

If your using an GIF and PNG try dropping a color from the table, should let you allocate another.
up
2
mlse
18 years ago
Another more general variation on the theme using the same naming conventions as the hexdec and dechex built-in functions ...

Prototype:

array hexrgb ( string hex_string )

Returns:

An associative array of the RGB components specified in hex_string.

hexrgb() example:

<?php
$rgb
= hexrgb("0xAABBCC");
print_r($rgb);
?>

Output is:

Array
(
[red] => 170
[green] => 187
[blue] => 204
)

Implementation:

<?php
function hexrgb ($hexstr)
{
$int = hexdec($hexstr);

return array(
"red" => 0xFF & ($int >> 0x10),
"green" => 0xFF & ($int >> 0x8),
"blue" => 0xFF & $int);
}
?>

The output of hexdec can then be passed to imagecolorallocate and manipulated as required.
up
2
mail at kailashnadh dot name
18 years ago
This nifty function will produce the negative of a given image!

<?php

/********************************

Code by Kailash Nadh
http://kailashnadh.name

usage:
img2neg("my_pic.jpg");

*********************************/

function img2neg($pic) {

header("Content-type: image/jpeg");

$source=imagecreatefromjpeg($pic); // Source
$width=imagesx($source); $height=imagesy($source);

$im = imagecreatetruecolor($width, $height); // Our negative img in the making

for($y=0; $y < $height; $y++) {
for(
$x=0; $x < $width; $x++) {

$colors=imagecolorsforindex($source, imagecolorat($source, $x,$y));

// this is what makes the colors negative
$r=255-$colors['red'];
$g=255-$colors['green'];
$b=255-$colors['blue'];
$test=imagecolorallocate($im, $r,$g,$b);
imagesetpixel($im,$x, $y, $test);
}
}

imagejpeg($im);
imagedestroy($im);
}

?>
up
2
mv at brazil dot com
19 years ago
<?php

/**
* Create a image bar using lib GD
* Ege. <img src="color_sample.php?color=FF0000" width="10 height="30">
*/

// Split the HTML color representation
$hexcolor = str_split($_GET["color"], 2);

// Convert HEX values to DECIMAL
$bincolor[0] = hexdec("0x{$hexcolor[0]}");
$bincolor[1] = hexdec("0x{$hexcolor[1]}");
$bincolor[2] = hexdec("0x{$hexcolor[2]}");

$im = ImageCreate(100, 100);
$colorallocate = ImageColorAllocate($im, $bincolor[0], $bincolor[1], $bincolor[2]);
ImageFilledRectangle($im, 0, 0, 100, 100, $colorallocate);
header('Content-Type: image/png');
ImagePNG($im);

?>
up
0
Zigbigidorlu at hotmail dot com
18 years ago
Here's a very simple and very effective code to change a HEX color to RGB.

<?php
function HEX2RGB($color){
$color_array = array();
$hex_color = strtoupper($color);
for(
$i = 0; $i < 6; $i++){
$hex = substr($hex_color,$i,1);
switch(
$hex){
case
"A": $num = 10; break;
case
"B": $num = 11; break;
case
"C": $num = 12; break;
case
"D": $num = 13; break;
case
"E": $num = 14; break;
case
"F": $num = 15; break;
default:
$num = $hex; break;
}
array_push($color_array,$num);
}
$R = (($color_array[0] * 16) + $color_array[1]);
$G = (($color_array[2] * 16) + $color_array[3]);
$B = (($color_array[4] * 16) + $color_array[5]);
return array(
$R,$G,$B);
unset(
$color_array,$hex,$R,$G,$B);
}
?>
up
0
Anonymous
19 years ago
When you are using truecolor images, you can also use bitwise operations to generate the color:
<?php
$color
= ($r << 16) | ($g << 8) | $b; // 2261213
?>
This is identical to the imagecolorallocate() function, in truecolor images!
up
-1
leif at harmsen dot net
20 years ago
I was unable to get any of the posted methods for converting colour to grayscale to work. The problem appears to be the way gd creates images from jpeg inconsistently over various versions. Eventually I wrote my own that works for me - this approach allocates the 256 color pallete first. You can also play with separate $r, $g, $b variables before using imagecolorallocate in order to tone or tint the image.

<?php
$resource
= 'whatever.jpg';
$im_size = GetImageSize($resource);
$imageWidth = $im_size[0];
$imageHeight = $im_size[1];
$im = imageCreate($imageWidth,$imageHeight);
for (
$c = 0; $c < 256; $c++) {
ImageColorAllocate($im, $c,$c,$c);
}
$im2 = ImageCreateFromJpeg($resource);
ImageCopyMerge($im,$im2,0,0,0,0, $imageWidth, $imageHeight, 100);
ImageDestroy($im2);
?>

go on using $im as your image, it is now grayscale ....
up
-3
divinity76 at gmail dot com
8 years ago
you have VERY limited space for color indexes (255 indexes on my system, with over 10 GB ram available, cli, no memory limit), when there is no more indexes available, imagecolorallocate will return false. when you create 2x indexes with the same r/g/b, you waste this very limited space. the function below should never fail, AND never waste any color index space. if there's already an index with the rgb, it will return the existing index, else it will try allocate 1, in the event that allocation fail (presumably because all index space is used up already), it will return the closest match to what you requested, and warn you via $couldFindExact.

function myimagecolorallocate($gd,int $red,int $green,int $blue,bool &$couldFindExact=null):int{
$ret=imagecolorexact($gd, $red, $green, $blue);
if($ret===-1){
$ret=imagecolorallocate($gd, $red, $green, $blue);
if($ret===false){
$couldFindExact=false;//out of color indexes (255 index by default..wish i knew why)
$ret=imagecolorclosest($gd, $red, $green, $blue);
} else {
$couldFindExact=true;
}
} else {
$couldFindExact=true;
}
return $ret;
}
To Top