imagecolorallocate

(PHP 3, PHP 4, PHP 5)

imagecolorallocate -- 为一幅图像分配颜色

说明

int imagecolorallocate ( resource image, int red, int green, int blue )

imagecolorallocate() 返回一个标识符,代表了由给定的 RGB 成分组成的颜色。image 参数是 imagecreatetruecolor() 函数的返回值。redgreenblue 分别是所需要的颜色的红,绿,蓝成分。这些参数是 0 到 255 的整数或者十六进制的 0x00 到 0xFF。imagecolorallocate() 必须被调用以创建每一种用在 image 所代表的图像中的颜色。

注: 第一次对 imagecolorallocate() 的调用会填充背景色。

<?php
$im
= imagecreatetruecolor('example.jpg');
// 背景设为红色
$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);
?>

如果分配失败则返回 -1。

参见 imagecolorallocatealpha()imagecolordeallocate()


add a note add a note User Contributed Notes
LPEspecial at home dot nl
19-Sep-2006 11:04
This might help someone who want to  use 'ImageColorAllocate ' with a hex value

function ImageColorAllocateFromHex ($img, $hexstr)
{
  $int = hexdec($hexstr);

  return ImageColorAllocate ($img,
         0xFF & ($int >> 0x10),
         0xFF & ($int >> 0x8),
         0xFF & $int);
}
behun at webconsult dot sk
27-Aug-2006 04:56
Also, when you need more then 256 colors, use imagecreatetruecolor function. With this function you can use unlimited number of colors.
erik at phpcastle dot com
03-Apr-2006 03:45
Hi,

During developing a gradient method I discovered that there can only be 255 colors allocated somehow...

So the first 255 are going ok and after these the colorallocate function returns -1. My work around for this problem was to put the allocated color in an array and check if this variable exists before calling imagecolorallocate again.

Did not had this problem again and my gradient scaled well after discovering this :)

This is the piece of code that created a gradient PNG. The code is top down programmed and not put in a function or class yet.

Because the code is 124 lines of code I've put the script at my website: http://beta.phpcastle.com/snippets/PHP/Image+Gradient (website still beta :P)

I hope someone can use this addition
SW
14-Jan-2006 06:00
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");
?>
mlse
15-Nov-2005 05:49
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.
miked at m80im dot com
08-Nov-2005 09:40
improvement upon fromhex function by avi at amarcus dot com

<?php
  
  
function fromhex($string,&$image) {
    
sscanf($string, "%2x%2x%2x", $red, $green, $blue);
     return
ImageColorAllocate($image,$red,$green,$blue);
   }
  
  
//Example for calling a hex color:
  
ImageFill($image, 0, 0, fromhex('FFFFFF'));

?>
Zigbigidorlu at hotmail dot com
07-Oct-2005 03:05
Here's a very simple and very effective code to change a HEX color to RGB.

-------------------------

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);
}

-------------------------
mail at kailashnadh dot name
28-Jun-2005 10:47
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);
}

?>
andreoli dot carlo at libero dot it
08-Jun-2005 09:38
hsl to RGB
(not yet optimized but it function)

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);
}
mv at brazil dot com
16-Mar-2005 03:34
<?

/**
 * 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);

?>
bob at hotmail dot com
11-Mar-2005 07:24
The first color allocated will not fill the background if you use a true color image from imagecreatetruecolor().
19-Jan-2005 06:23
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!
aaron at parecki dot com
22-Dec-2004 06:10
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);

?>
carlosreche at yahoo dot com
14-Dec-2004 12:27
Here is an easier way to set the color without use imagecolorallocate();

<?php

$image
= imagecreatetruecolor();

imagefill($image, 0, 0, 0xFFFFFF); // white color (#FFFFFF)

?>

Use hexadecimal values just like you do in HTML codes:

0xFF0000 = red
0x00FF00 = green
0x0000FF = blue
0xFFFF00 = yellow

... and so on

Hope this will help many people...

Carlos Reche
tyberis
28-Nov-2004 08:58
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]));
 }
}
?>
avi at amarcus dot com
20-Aug-2004 02:21
quote from "tim at phantomrpg dot com"

Here is a simpler way of using a hex color with ImageColorAllocate().
sscanf("FFFF00", "%2x%2x%2x", $red, $green, $blue);
$stringColor=ImageColorAllocate($image,$red,$green,$blue);

I made it into a simple function:
<?php
function fromhex($string){
   GLOBAL
$image;
  
sscanf($string, "%2x%2x%2x", $red, $green, $blue);
   return
ImageColorAllocate($image,$red,$green,$blue);
   }
//Example for calling a hex color:
ImageFill($image, 0, 0, fromhex('FFFFFF'));
?>
smoli at paranoya dot ch
20-Jul-2004 02:10
Some of you maybe want to use HSV color model for drawing color selectors and circles:

<?
 
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;
  }
?>
tim at phantomrpg dot com
04-Apr-2004 06:38
Here is a simpler way of using a hex color with ImageColorAllocate().

sscanf("FFFF00", "%2x%2x%2x", $red, $green, $blue);
$stringColor=ImageColorAllocate($image,$red,$green,$blue);

Hope it helps someone.
jernberg at fairytale dot se
06-Mar-2004 02:43
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 );
chris at drunkenpirates dot co dot uk
14-Sep-2003 08:44
<?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);
?>
BruceB
20-May-2003 12:39
Doiveo's suggestion for getting the font colors to behave with JPEG's does (at least for PHP 4.1.2 - GD version 1) stop the problem (that I had) with fonts becoming outlined instead of solid, however the font colors were still incorrect.

There is however a much simpler (and faster) solution, just use imageColorClosest instead of imageColorAllocate, e.g:

$near_white = imageColorClosest($img, 255,255,255);
imageTTFtext($img, 10, 0, 20, 20, $near_white, "font file path", "text to add to JPEG");

For most JPEG's there should be a fairly close matching color to the one you want to use.
leif at harmsen dot net
16-Apr-2003 10:31
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 ....
jasper at pointless dot net
21-Jan-2003 09:20
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 < path/to/patch

and recompile and reinstall.
bisqwit at iki dot fi
17-Feb-2002 12:30
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.
bisqwit at iki dot fi
17-Feb-2002 05:20
Looks like this function only allows allocating of 256 distinct colours.

So this code:
  <?php
  $im
= ImageCreate(500,200);
  for(
$a=0; $a<500; $a++)
  {
  
$c = 128 + sin($a) * 127;
  
ImageLine($im, $a,0, $a,199, ImageColorAllocate($im, $c,$c,$c));
  }
 
ob_start();
 
ImageJpeg($im, '', 75);
 
$s = ob_get_contents();
 
ob_end_clean();

 
header('Content-type: image/jpeg');
 
header('Content-length: '.strlen($s));
  print
$s;

will make an image that has changing colours at
the first 256 pixel columns only
. The rest are gray.
doiveo at hotmail dot nospam
12-Jan-2002 02:17
This will help anyone trying to control font colors in a JPEG. You have to create a temporary image first, allocate the colors then merge the images before it works. Go figure.

$im_size = GetImageSize ( "MySource.jpg" );
$imageWidth = $im_size[0];
$imageHeight = $im_size[1];

$im = imageCreate( $imageWidth, $imageHeight );

// - or with GD 2+ -
// $im = imageCreateTrueColor( $imageWidth, $imageHeight );

// do all your color allocations here
$font_color_black = ImageColorAllocate( $im, 0,0,0);

$im2 = ImageCreateFromJPEG("MySource.jpg");

ImageCopy ($im,$im2,0,0,0,0, $imageWidth, $imageHeight);
ImageDestroy ($im2);

...finish as you please using the $im var.