用户评论:
[#1]
phillip dot gooch at gmail dot com [2010-12-08 19:52:40]
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.
[#2]
jahservant 13 at gmail dot com [2009-11-24 16:55:36]
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:
//test if we have used up paletteif(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:
// [...]imagecolorallocate($pic,125,125,125);//returns 23imagecolorallocate($pic,125,125,125);//returns 25
// [...]
// etc...?>
So here, imagecolorexact() is useful:
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:
//get color from palette$color=imagecolorexact($pic,$c1,$c2,$c3);
if($color==-1) {//color does not exist...
//test if we have used up paletteif(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:
if($color==-1) {//color does not exist...
//test if we have used up paletteif(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...}?>
[#3]
Ludo [2007-10-24 14:35:40]
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 :
[#4]
William Barath [2007-09-28 16:15:10]
Lots of hsv2rgb commentary but no working example, so here's mine:
{$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) {
case0: return array($v,$t,$p);
case1: return array($q,$v,$p);
case2: return array($p,$v,$t);
case3: return array($p,$q,$v);
case4: 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);?>
[#5]
picklecj at rose-hulman dot edu [2007-06-13 08:15:46]
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.
$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
}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.
[#6]
behun at webconsult dot sk [2006-08-27 01:56:31]
Also, when you need more then 256 colors, use imagecreatetruecolor function. With this function you can use unlimited number of colors.
[#7]
SW [2006-01-13 14:00:05]
This works! A Black-Image with vertical centered white Aliased Arial-Text and same left and right margin - used for Menu-Buttons.
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");?>
[#8]
mlse [2005-11-15 01:49:46]
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:
$rgb=hexrgb("0xAABBCC");print_r($rgb);?>
Output is:
Array
(
[red] => 170
[green] => 187
[blue] => 204
)
Implementation:
{$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.
[#9]
Zigbigidorlu at hotmail dot com [2005-10-06 12:05:20]
Here's a very simple and very effective code to change a HEX color to RGB.
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);
}?>
[#10]
mail at kailashnadh dot name [2005-06-28 07:47:30]
This nifty function will produce the negative of a given image!
for($x=0;$x
}
}imagejpeg($im);imagedestroy($im);
}?>
[#11]
andreoli dot carlo at libero dot it [2005-06-08 06:38:58]
hsl to RGB
(not yet optimized but it function)
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);
}?>
[#12]
mv at brazil dot com [2005-03-15 11:34:31]
[#13]
[2005-01-18 14:23:40]
When you are using truecolor images, you can also use bitwise operations to generate the color:
$color= ($r<<16) | ($g<<8) |$b;// 2261213?>
This is identical to the imagecolorallocate() function, in truecolor images!
[#14]
aaron at parecki dot com [2004-12-22 02:10:49]
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.
$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);?>
[#15]
tyberis [2004-11-28 04:58:43]
2 functions to convert from HSV colorspace (hue/saturation/brightness) to RGB (red/green/blue) colorspace and back.
// $red=[0..1], $green=[0..1], $blue=[0..1];functionrgb2hsv($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]functionhsv2rgb($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".
[#16]
smoli at paranoya dot ch [2004-07-19 11:10:01]
Some of you maybe want to use HSV color model for drawing color selectors and circles:
{$ret= newstdClass();
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)
{
case0:$ret->r=$v;$ret->g=$t;$ret->b=$w; break;
case1:$ret->r=$q;$ret->g=$v;$ret->b=$w; break;
case2:$ret->r=$w;$ret->g=$v;$ret->b=$t; break;
case3:$ret->r=$w;$ret->g=$q;$ret->b=$v; break;
case4:$ret->r=$t;$ret->g=$w;$ret->b=$v; break;
case5:$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;
}?>
[#17]
jernberg at fairytale dot se [2004-03-05 10:43:35]
this might help someone, how to allocate an color from an html color-definition:
$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);?>
[#18]
chris at drunkenpirates dot co dot uk [2003-09-13 17:44:56]
}//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
for($x=0;$x
}
}
for($y=0;$y
for($x=0;$x
}
}//SET PIXELSfor($y=0;$y
for($x=0;$x
}
}//RESIZE IMAGE FOR DISPLAYImagecopyresized($imB,$imA,0,0,0,0,$width*4,$height*4,$width,$width);ImagePNG($imB);?>
[#19]
leif at harmsen dot net [2003-04-15 19:31:02]
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.
$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 ....
[#20]
jasper at pointless dot net [2003-01-20 17:20:16]
a patch to php 4.3.0 to add imagecolorallocatealpha is here:
http://pointless.net/~jasper/php-4.3.0-imagecolorallocatealpha.patch
cd php-4.3.0/ext/gd
patch
and recompile and reinstall.
[#21]
bisqwit at iki dot fi [2002-02-16 20:30:57]
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.