Page 1 of 1

[SOLVED]Coloring pixels with alpha channel

Posted: Tue Nov 20, 2007 7:14 am
by Rovas
I want to replace a color that has alpha channel with one picked by the user but saving the alpha channel in the process. I look on the web and this is done only for png images, I need for gifs and jpg images. The code I made is the common script for replacing colors in an image.

Code: Select all

//rgb is the color picked by the user
$red=hexdec(substr($rgb,0,2));
$green=hexdec(substr($rgb,2,2));
$blue=hexdec(substr($rgb,4,2));	
for($i=0;$i<imagecolorstotal($im);$i++){		
  $col=ImageColorsForIndex($im,$i);
  $red_set=$red/255*$col['red']+$ligtht;
  $green_set=$green/255*$col['green']+$ligtht;
  $blue_set=$blue/255*$col['blue']+$ligtht;
  if($col['alpha']<=126) {$alpha=$col['alpha'];}
}

P.S. Sorry about the formating but the Post new topic textarea message doesn' t jump to a new line when I press Enter in FF 2.0.9 .
Edit: ^ Today it works.

Posted: Wed Nov 21, 2007 8:44 am
by Rovas
Made some changes to the script but this time the image isn' t displayed and no error message are shown.

Code: Select all

function ImageColorWithTransparency($im, $rgb){
	/*creating a true color replica */
	$x=imagesx($im);
	$y=imagesy($im);
	$im1=imagecreatetruecolor($x,$y);
         $j=0; 
	$ligtht=0;
	$red=hexdec(substr($rgb,0,2));
	$green=hexdec(substr($rgb,2,2));
	$blue=hexdec(substr($rgb,4,2));
	for($i=0;$i<imagecolorstotal($im);$i++){
		$col=ImageColorsForIndex($im,$i); 
		if($col['alpha']>=126 && j==0){
				imagecolortransparent($im,$i);
				imagefill($im1,0,0,$cul);
				$j++;
			}
			else{
				$red_set=$red/255*$col['red']+$ligtht;
				$green_set=$green/255*$col['green']+$ligtht;
				$blue_set=$blue/255*$col['blue']+$ligtht;
			}
			if($red_set>255)$red_set=255;
			if($green_set>255)$green_set=255;
			if($blue_set>255)$blue_set=255;
			if($red_set<0)$red_set=0;
			if($green_set<0)$green_set=0;
			if($blue_set<0)$blue_set=0;
			imagecolorset($im1,$i,$red_set,$green_set,$blue_set); 
	}
	return $im1;
	imagedestroy($im1);
}

Posted: Wed Nov 21, 2007 8:51 am
by onion2k
ImageColorsForIndex() won't work for JPEGs or 24bit (32bit) PNG files. But ignoring that..

How are you trying to display the image?

Posted: Wed Nov 21, 2007 10:16 am
by John Cartwright

Code: Select all

return $im1;
   imagedestroy($im1);
FYI, functions are terminated when they hit a return.. so your imagedestroy() will never be fired.

Posted: Thu Nov 22, 2007 1:46 am
by Rovas
Thank you JCart for that tip.
onion2k: The display format is gif. That' s way I don' t use

Code: Select all

imagealphablending()
//and
imagesavealpha();
I put some echo in the function and found out that the transparent color is correctly identified for gifs, the formula is good but I didn' t find out why is not making the image :( .

Posted: Thu Nov 22, 2007 6:47 am
by onion2k
Without seeing the code you're using to try to output the image there's not much anyone can do to help.

Posted: Thu Nov 22, 2007 7:09 am
by Rovas
I changed the function a bit after I observed that in gif image the last color is the one with the transparent pixels, added the header for the image but it still doesn' t save transparency and for some images it omits some parts of it.

Code: Select all

function ImageColorWithTransparency($im, $rgb){
        $j=0; 
	$ligtht=0;
	
	$red=hexdec(substr($rgb,0,2));
	$green=hexdec(substr($rgb,2,2));
	$blue=hexdec(substr($rgb,4,2));
	
	//echo "Before the  for <br />";
	for($i=0;$i<imagecolorstotal($im);$i++){
		$col=imagecolorsforindex($im,$i); 
	         if($col['alpha']>=126 &&$j==0){
				$id=imagecolortransparent($im);
				//echo " <h5>Transparent color found:" .$sir."!</h5> <br />";
				//echo "Id is: " .$id; 
				imagecolortransparent($im,$id);
				imagefill($im,0,0,$id);
				$j++;
			}
			else{
				//echo "It changes color at stepl " .$i ."<br />";
				$red_set=$red/255*$col['red']+$ligtht;
				$green_set=$green/255*$col['green']+$ligtht;
				$blue_set=$blue/255*$col['blue']+$ligtht;
				if($red_set>255)$red_set=255;
				if($green_set>255)$green_set=255;
				if($blue_set>255)$blue_set=255;
				if($red_set<0)$red_set=0;
				if($green_set<0)$green_set=0;
				if($blue_set<0)$blue_set=0;
			}
			//echo "Color image <br />";
			imagecolorset($im,$i,$red_set,$green_set,$blue_set); 
	}
	return $im;
}

$path="../css/pics/";
$col="";
if(!isset($_GET['rgb'])) $col="000000";
else{$col=$_GET['rgb'];}
if(!isset($_GET['file'])){echo "file is not defined"; exit;}
else{
	$im=$path .$_GET['file'];
	//echo $im;
	$imag=imagecreatefromgif($im);
	$pict=ImageColorWithTransparency($imag, $col);
	header("Content-type:image/gif");
	imagegif($pict);
	imagedestroy($pict);
}

Posted: Fri Nov 23, 2007 5:57 am
by Rovas
I made it work by removing some echo that I forgot to comment :oops: . But it only works for some gifs while for others it puts transparent pixels where there aren' t in the original (i. e. changes their alpha channel) :( .

Posted: Fri Nov 30, 2007 1:28 am
by Rovas
The solution is pretty simple just use imagecolorset, there is no need to verify which color has alpha channel but only for gifs.