Bouncy Xbox LIVE Gamertar GD code explained

If you don’t already know Bouncy Xbox Live is a new script from BouncyServers which allows your community to add there Xbox Live gamertag to your forum so that your community can easily find and play games with other members.

One of the cool features which was included with Bouncy Xbox Live was the Gamertar. This was basically a small dynamic avatar image which was generated on the fly using a background image and the members Xbox Live avatar. This meant that because it was generated on the fly, the Gamertar would always display the gamers latest avatar style such as hair, clothes and facial features.

To the left you can see my current gamertar, this will automatically change if and when i update my Xbox live avatar. This uses the default Bouncy Xbox Live Gamertar background with a grey border and a golden glow.

Onto the technical stuff.

The gamertar is generated using 2 PHP functions and the GD image library.

The first function is called create_gamertar()

function create_gamertar ()
{
//-------------------------
// Fetch And Clean Gamertag
//-------------------------
$gamertag	 = $this->ipsclass->input['tag'];
$gamertag = ereg_replace("[[:space:]]+", "%20", $gamertag);
//-----------------------
// Fetch Gamertar Images
//-----------------------
$img_a = imagecreatefrompng("{$this->ipsclass->vars['img_url']}/bxbl_images/gavbg.png");
$img_b = "http://avatar.xboxlive.com/avatar/{$gamertag}/avatar-body.png";
//---------------------
// Set Max Avatar Size
//---------------------
$width = 80;
$height = 160;
//--------------------
// Get New Dimensions
//--------------------
list($width_orig, $height_orig) = getimagesize($img_b);
$ratio_orig = $width_orig/$height_orig;
if ($width/$height > $ratio_orig)
{
	$width = $height*$ratio_orig;
}
else
{
	$height = $width/$ratio_orig;
}
//----------
// Resample
//----------
$image_p = imagecreatetruecolor($width, $height);
imagecolortransparent($image_p, imagecolorallocate($image_p, 0, 0, 0));
imagealphablending($image_p, false);
imagesavealpha($image_p, true);
$image = imagecreatefrompng($img_b);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
//---------------------------------------
// Copy, Merge, Resize With Transparency
//---------------------------------------
$this->imagecopymerge_alpha($img_a, $image_p, 0, 0, 10, 10, 64, 57,100);
//---------------
// Output Images
//---------------
header("Content-Type: image/png");
imagesavealpha($img_a, true);
imagepng($img_a, NULL);
imagedestroy($img_a);
imagedestroy($img_b);
}

pretty straight forward function so lets go over each step

First of all

//-------------------------
// Fetch And Clean Gamertag
//-------------------------
$gamertag	 = $this->ipsclass->input['tag'];
$gamertag = ereg_replace("[[:space:]]+", "%20", $gamertag);

as mentioned in the quote, this fetches and cleans the gamertag, this has to be done firstly because gamertag’s can contain spaces between characters, and secondly because sometimes i like to obey the standards. So this function first of all saves the members gamertag in the $gamertag variable and then converts any spaces to %20 so it would turn “Anthony Kinson” into “Anthony%20Kinson”.

The next piece of code…

//-----------------------
// Fetch Gamertar Images
//-----------------------
$img_a = imagecreatefrompng("{$this->ipsclass->vars['img_url']}/bxbl_images/gavbg.png");
$img_b = "http://avatar.xboxlive.com/avatar/{$gamertag}/avatar-body.png";
//---------------------
// Set Max Avatar Size
//---------------------
$width = 80;
$height = 160;
//--------------------
// Get New Dimensions
//--------------------
list($width_orig, $height_orig) = getimagesize($img_b);
$ratio_orig = $width_orig/$height_orig;
if ($width/$height > $ratio_orig)
{
	$width = $height*$ratio_orig;
}
else
{
	$height = $width/$ratio_orig;
}

OK, so nice brief explanation. img_a grabs the Gamertars background image i previously mentioned from the forums skin directory (this allows a different background for each installed skin) and img_b retrieves the members avatar using the previously formatted gamertag.

After this the avatars width and height are edited, this allows us to shrink the avatar so it fits in the Gamertar. The next block of code sets the new dimensions maintaining the aspect ratio.

//----------
// Resample
//----------
$image_p = imagecreatetruecolor($width, $height);
imagecolortransparent($image_p, imagecolorallocate($image_p, 0, 0, 0));
imagealphablending($image_p, false);
imagesavealpha($image_p, true);
$image = imagecreatefrompng($img_b);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);

The above code then resample’s the image whilst maintaining aspect ratio and pixel transparency within the png. This lead to a problem and the creation of the second function imagecopymerge_alpha(). As it goes, when you merge 2 images using GD in PHP specifically PNG images, the transparency is lost, resulting in a solid black background being applied to the avatar image, the problem with this is that it just creates a cropped avatar with a black background and the gamertar background is not visible.

//---------------------------------------
// Copy, Merge, Resize With Transparency
//---------------------------------------
$this->imagecopymerge_alpha($img_a, $image_p, 0, 0, 10, 10, 64, 57,100);

This is where the above bit of code comes into play. This bit of code then sends our avatar to the imagecopymerge_alpha() function with all the data needed.

So, here is the imagecopymerge_alpha() function…

function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct){
if(!isset($pct))
{
return false;
}
$pct /= 100;
//---------------------------
// Get Image Width And Height
//---------------------------
$w = imagesx( $src_im );
$h = imagesy( $src_im );
//-------------------------
// Turn Alpha Blending Off
//-------------------------
imagealphablending( $src_im, false );
//-----------------------------------------
// Find The Most Opaque Pixel In The Image
//-----------------------------------------
$minalpha = 127;
for( $x = 0; $x < $w; $x++ )
for( $y = 0; $y < $h; $y++ )
{
$alpha = ( imagecolorat( $src_im, $x, $y ) >> 24 ) & 0xFF;
if( $alpha < $minalpha )
{
$minalpha = $alpha;
}
}
//----------------------------------------------------
// Loop Through Image Pixels And Modify Alpha For Each
//----------------------------------------------------
for( $x = 0; $x < $w; $x++ )
{
for( $y = 0; $y < $h; $y++ )
{
//-----------------------------------------------------
// Get Current Alpha Value (Represents The Transparency)
//-----------------------------------------------------
$colorxy = imagecolorat( $src_im, $x, $y );
$alpha = ( $colorxy >> 24 ) & 0xFF;
//--------------------
// Calculate New Alpha
//--------------------
if( $minalpha !== 127 )
{
$alpha = 127 + 127 * $pct * ( $alpha - 127 ) / ( 127 - $minalpha );
}
else
{
$alpha += 127 * $pct;
}
//-----------------------------------
// Get The Colour Index With New Alpha
//-----------------------------------
$alphacolorxy = imagecolorallocatealpha( $src_im, ( $colorxy >> 16 ) & 0xFF, ( $colorxy >> 8 ) & 0xFF, $colorxy & 0xFF, $alpha );
//---------------------------------------
// Set Pixel With The New Colour + Opacity
//---------------------------------------
if( !imagesetpixel( $src_im, $x, $y, $alphacolorxy ) )
{
return false;
}
}
}
//---------------
// The Image Copy
//---------------
imagecopy($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
}

There is no point in me going over each detail of this function, it pretty mush stays the same however you use it. As you can see from the code quotes it basically finds the most opaque pixel and then calculates the new alpha blending. After which it is returned back to the create_gamertar() function. and is output through the following final piece of code

//---------------
// Output Images
//---------------
header("Content-Type: image/png");
imagesavealpha($img_a, true);
imagepng($img_a, NULL);
imagedestroy($img_a);
imagedestroy($img_b);

Above again is pretty simple. It just sets the output content type, in this case, its a PMG image.

This code can be pretty much be used stand alone, of course though, you will need to create some sort of switch or post info so for example the URL http://yoursite.com/gamertar.php?gamertag=Anthony%20Kinson would set the gamertag to be used as Anthony Kinson something maybe like $gamertag = $_POST[‘gamertag’];

its completely up to you how you go about it, but these are the basic principles to how the gamertar is created.