Page 1 of 1

GD dynamic Image composite

Posted: Tue Jun 14, 2005 7:48 pm
by josh2xsv
Hi Everyone - Hope someone can give me some feedback on the following code...
Its giving me some unexpected results-(namely not implementing/keeping the col2(color on layer 2) I am fairly new to GD so my code may be a bit basic...(or shocking )

Code: Select all

<?php
/**--------------------------------------------------------------------------------------|
| Produced with heaps of help from PHP Communities worldwide by JOSH REID for Diamond NZ                  |
| 																						 |
|       CREATES A MULTI LAYER VARIABLE CONTROLLED IMAGE FROM BLACK & WHITE GIFS		 	 |
|--------------------------------------------------------------------------------------**/ 

// Select Source Main Pictures 
	if ($product1 == "DSG Overalls") {
		$layer1_file = "dsg_yoke.gif";
		$layer2_file = "dsg_main.gif";
		$layer3_file = "dsg_out.gif";
	} else if ($product1 == "Easy Action Overalls") {
		$layer1_file = "ea_yoke.gif";
		$layer2_file = "ea_main.gif";
		$layer3_file = "ea_out.gif";
	} else { // Fall back to DSG (no selection - testing)
		$layer1_file = "dsg_yoke.gif";
		$layer2_file = "dsg_main.gif";
		$layer3_file = "dsg_out.gif";
	}
	
// Select Source Fastening Picture
$fastening == "Zip" ? $layer4_file = "zip.gif": $layer4_file = "dome.gif";

/** COLORS **/
// $col1 vars to hex
$col1 == "White" ? $col1_hex = "#FFFFFF" : "";
$col1 == "Tele Grey" ? $col1_hex = "#AAAAAA" : "";
$col1 == "Grey" ? $col1_hex = "#666666" : "";
$col1 == "Red" ? $col1_hex = "#FF0000" : "";
$col1 == "Med Blue" ? $col1_hex = "#0042AD" : "";
// (...etc etc etc)

// $col2 vars to hex
$col2 == "White" ? $col2_hex = "#FFFFFF" : "";
$col2 == "Tele Grey" ? $col2_hex = "#AAAAAA" : "";
$col2 == "Grey" ? $col2_hex = "#666666" : "";
$col2 == "Red" ? $col2_hex = "#FF0000" : "";
$col2 == "Med Blue" ? $col2_hex = "#0042AD" : "";
// (...etc etc etc)

// Hex 2 rgb functions
function hex2rgb($hex) {
		$color = str_replace('#', '', $hex);
		$ret = array(
		'r' => hexdec(substr($color, 0, 2)),
		'g' => hexdec(substr($color, 2, 2)),
		'b' => hexdec(substr($color, 4, 2))
  		);
	return $ret;
}
// Set Col1 & Col2 RGB (Call Hex2rgb)
$col1_rgb = hex2rgb($col1_hex);
$col2_rgb = hex2rgb($col2_hex);

/**-------------------------------|
|      COLOR LAYER IMAGE COMPOSITE     |
|-------------------------------**/

// $findblack rgb array
$findblack = array('r' => 0, 'g' => 0, 'b' => 0);
// Function find color index array
function getColorFromColorIndex($color){
        $array = array();
        $array['r'] = ($color  >> 16) & 0xFF; 
        $array['g'] = ($color  >>  & 0xFF; 
        $array['b'] = $color  & 0xFF; 
        return $array;
    }

/** FIRST STEP **/
// LAYER 1
$im_src1 = imagecreatefromgif($layer1_file);
	for($x = 0;$x < 300;$x++){
		for($y = 0;$y < 335;$y++){ 
			$color1 = getColorFromColorIndex(imagecolorat($im_src1,$x,$y));
				// BLACK - Set to $col1
				if($color1 == $findblack){
                   $colors1 = imagecolorallocate($im_src1,$col1_rgb['r'],$col1_rgb['g'],$col1_rgb['b']); 
                   imagesetpixel($im_src1,$x,$y,$colors1);
                }
            }
        }
	imagealphablending($im_src1, true); 

/** NEXT STEP **/
// LAYER 2
$im_src2 = imagecreatefromgif($layer2_file);
	for($x = 0;$x < 300;$x++){
		for($y = 0;$y < 335;$y++){ 
			$color2 = getColorFromColorIndex(imagecolorat($im_src2,$x,$y));
				// BLACK - Set to $col2
				if($color2 == $findblack){
                   $colors2 = imagecolorallocate($im_src2,$col2_rgb['r'],$col2_rgb['g'],$col2_rgb['b']); 
                   imagesetpixel($im_src2,$x,$y,$colors2);
                }
            }
        }

/** MERGE FIRST 2 LAYERS **/
imagecopymerge($im_src1,$im_src2,0,0,0,0, 300,335, 100);
imagedestroy($im_src2);

/** NEXT STEP **/
// LAYER OUTLINE
$im_outline = imagecreatefromgif($layer3_file);
// Set Transparent
$black = imagecolorallocate ($im_outline, 0, 0, 0);
$grey = imagecolorallocate ($im_outline, 0xAC, 0xAC, 0xAC);
$white = imagecolorallocatealpha ($im_outline, 255, 255, 255, 127);

/** NEXT STEP **/
// LAYER FASTENING
$im_fast = imagecreatefromgif($layer4_file);
// Set Transparent
$black = imagecolorallocate ($im_fast, 0, 0, 0);
$white = imagecolorallocatealpha ($im_fast, 255, 255, 255, 127);

/** LAST STEP **/
// MERGE Outline & Fastening to coloured layer
imagecopymerge($im_src1,$im_outline,0,0,0,0, 300,335, 100);
imagecopymerge($im_src1,$im_fast,0,0,0,0, 300,335, 100);

// Destroy last imgs not needed
imagedestroy($im_outline);
imagedestroy($im_fast);

/** OUTPUT **/
header("Content-type: image/jpeg");
imagejpeg($im_src1,"",100);

?>
Link to testing page to see what its doing http://www.diam.co.nz/yakka/testform.php

I would appreciate any feedback :roll: - THANKS HEAPS!

Posted: Wed Jun 15, 2005 1:58 am
by Syranide
JPEGs don't use the palette which you are trying to use I'm pretty sure of... one could think there would be a logical translation, but often it is not as that would likely not work in practice. so, no use of colortables/palettes I guess. (assuming you are sending the correct color and so on)

sorry for double post!

Posted: Wed Jun 15, 2005 4:09 pm
by josh2xsv
Hey - Sorry for the double post it won't happen again! :oops:
---
I'll output as gif through testing see if I can't get it back to jpg later?!
I am working on creating the first layer with 3 distinct colors and set both replace colors on 1 file then merge with outlines etc. hopefully that can give me the result im after... let ya know!
Thanks for your help :wink:

GOT IT SORTED - YEHAA!!!

Posted: Wed Jun 15, 2005 5:48 pm
by josh2xsv
Thanks for your input- sorry to double post won't happen again!
I have solved it through using a png as layer 1 with 2 distinct colours - have replaced those 2 colours on 1 file then merged with outlines etc. I can now output as jpeg no stress!
Thanks
Josh :D :D

Re: GD dynamic Image composite

Posted: Fri Feb 03, 2012 10:39 pm
by stwalcher
Hey guys. Thanks for all the great help here. You helped me to figure out a couple of problems in my own script. It takes multiple color layers and a provided hex code to return a merged and colored image. Check out the script; you might even see your work in there!

Code: Select all

function hexLighter($hex, $factor = 30) {
	$new_hex = '';

	$base['R'] = hexdec($hex{0}.$hex{1});
	$base['G'] = hexdec($hex{2}.$hex{3});
	$base['B'] = hexdec($hex{4}.$hex{5});

	foreach ($base as $k => $v) {
		$amount = 255 - $v;
		$amount = $amount / 100;
		$amount = round($amount * $factor);
		$new_decimal = $v + $amount;

		$new_hex_component = dechex($new_decimal);

		$new_hex .= sprintf('%02.2s', $new_hex_component);
	}

	return $new_hex;
}

// Sanitize/Validate provided color variable
if (!isset($_GET['color']) || strlen($_GET['color']) != 6) {
	header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request', true, 400);

	exit(0);
}

if (file_exists( "cache/{$_GET['color']}.png" )) {
	header( 'Content-Type: image/png' );
	readfile( "cache/{$_GET['color']}.png" );

	exit(0);
}

// Desired final size of image
$n_width = 50;
$n_height = 50;

// Actual size of source images
$width = 125;
$height = 125;

$image = 	imagecreatetruecolor($width, $height);
			imagesavealpha($image, true);
			imagealphablending($image, false);

$n_image = 	imagecreatetruecolor($n_width, $n_height);
			imagesavealpha($n_image, true);
			imagealphablending($n_image, false);

$black = imagecolorallocate($image, 0, 0, 0);
$transparent = imagecolorallocatealpha($image, 255, 255, 255, 127);

imagefilledrectangle($image, 0, 0, $width, $height, $transparent);

$layers = array();
$layers_processed = array();

$layers[] = array( 'src' => 'layer01.gif', 'level' => 0 );	// Border
$layers[] = array( 'src' => 'layer02.gif', 'level' => 35 ); 	// Background
$layers[] = array( 'src' => 'layer03.gif', 'level' => 100 );	// White Quotes

foreach ($layers as $idx => $layer) {
	$img = imagecreatefromgif( $layer['src'] );
	$processed = imagecreatetruecolor($width, $height);

	imagesavealpha($processed, true);
	imagealphablending($processed, false);

	imagefilledrectangle($processed, 0, 0, $width, $height, $transparent);

	$color = hexLighter( $_GET['color'], $layer['level'] );
	$color = imagecolorallocate($image,
		hexdec( $color{0} . $color{1} ),
		hexdec( $color{2} . $color{3} ),
		hexdec( $color{4} . $color{5} )
	);

	for ($x = 0; $x < $width; $x++)
		for ($y = 0; $y < $height; $y++)
			if ($black === imagecolorat($img, $x, $y))
				imagesetpixel($processed, $x, $y, $color);

	imagecolortransparent($processed, $transparent);
	imagealphablending($processed, true);

	array_push($layers_processed, $processed);

	imagedestroy( $img );
}

foreach ($layers_processed as $processed) {
	imagecopymerge($image, $processed, 0, 0, 0, 0, $width, $height, 100);

	imagedestroy( $processed );
}

imagealphablending($image, true);

imagecopyresampled($n_image, $image, 0, 0, 0, 0, $n_width, $n_height, $width, $height);

imagealphablending($n_image, true);

header( 'Content-Type: image/png' );
imagepng( $n_image, "cache/{$_GET['color']}.png" );
imagepng( $n_image );

// Free up memory
imagedestroy( $n_image );
imagedestroy( $image );
If you want more information about that code, I have a detailed explaination on my blog.