Faux Email Links Using PHP

In an earlier post, Faux Email Links Using ASP .NET Image Handler, I wrote about generating images in code for email links using an ASP .NET generic handler. Wouldn’t it be nice to generate these same type of images in PHP? I wanted such a link for my resume, which is hosted on the same host as this blog. Well I guess I could have used Mono, but PHP is already installed for WordPress and ready to go.

The JavaScript is the same as for the ASP .NET image handler, you can get it from that post. The PHP code for the link is shown below:

Source for EmSpockBlam.php

<?php
//putenv('GDFONTPATH=/usr/share/fonts/msttcore/');
putenv('/usr/share/fonts/msttcorefonts/');

/* We will look for the following values in the query string
 *
 * addr : The encoded link address, required,
 * fnt  : Font, default value is arial.ttf.  Install msttffonts.
 * size : Font size, in points.  Default 10.
 * clr  : Link text color.  Default black.
 * bkg  : Link background.  Default white.
 * img  : Image format, can be 'png' or 'jpeg', default is 'png'.
 */

if (!isset($_GET['addr'])) {
    die("addr not set.");
}
$encLinkText = $_GET['addr'];

$font = 'arial.ttf';
if (isset($_GET['fnt'])) {
    $font = $_GET['fnt'];
}

$fontSize = 10;
if (isset($_GET['size'])) {
    $fontSize = (int) $_GET['size'];
}

$clr = "FF000000";
if (isset($_GET['clr'])) {
    $clr = $_GET['clr'];
}
$arrClr = _getARGB($clr);

$bkg = "FFFFFFFF";
if (isset($_GET['bkg'])) {
    $bkg = $_GET['bkg'];
}
$arrBkg = _getARGB($bkg);

$img = 'png';
if (isset($_GET['img'])) {
    $img = $_GET['img'];
    if ($img != 'jpeg') {
        $img = 'png';
    }
}

// decode the link text
$linkText = _decodeLinkText($encLinkText);


// First we create our bounding box for the text.  Add space so
// last character is not clipped.  This was empirically determined.
$bbox = imagettfbbox($fontSize, 0, $font, $linkText . ' ');

// Calculate height and widht of bounding box.
$width = abs($bbox[0]) + abs($bbox[2]);
$height = abs($bbox[5]) + abs($bbox[1]);


// Create true color image
$im = imagecreatetruecolor($width, $height);

// We'll support alpha for a png.  Does not hurt to have here if a jpeg, final
// image will not have transparency.
imagealphablending($im, false);
imagesavealpha($im, true);

// Get colors
$fore = imagecolorallocatealpha($im, $arrClr[1], $arrClr[2], $arrClr[3], $arrClr[0]);
$back = imagecolorallocatealpha($im, $arrBkg[1], $arrBkg[2], $arrBkg[3], $arrBkg[0]);

// Set the background color.
imagefilledrectangle($im, 0, 0, $width, $height, $back);

// This will blend text having alpha in its color with background.
imagealphablending($im, true);

// Link text.
imagettftext($im, $fontSize, 0, abs($bbox[0]), abs($bbox[5]), $fore, $font, $linkText);

// No underlining for text support in GD, draw our own line to simulate
// a hyplink.
imageline($im, 0, $height - 1, $width + 1, $height - 1, $fore);

// Set response header content type.
if ($img == 'png') {
    header('Content-type: image/png');
    imagepng($im);
}
else {
    header('Content-type: image/jpeg');
    imagejpeg($im);
}

// clean up.
imagedestroy($im);

// decode the link text
function _decodeLinkText($linkText)
{
    $s;
    $n;
    $retVal = '';
    for ($i = 0; $i < strlen($linkText);)
    {
        $s = $linkText[$i + 1] . $linkText[$i];
        $n = intval($s, 16);

        $n -= 0x6f;

        $retVal = $retVal . chr($n)  ;

        $i += 2;
    }

    return $retVal;
}

// Translate a 6 or 8 character hex encoded string to an array of values for ARGB.
function _getARGB($sArgb)
{
    $len = strlen($sArgb);

    // range for the alpha is 0 - 127, with 0 being opaque.
    $a = (intVal( (($len == 6) ? "FF" : substr($sArgb, 0, 2)), 16) >> 1);
    $a = 127 - $a;

    // get blue, green and red values.
    $b = intval(substr($sArgb, -2, 2), 16);
    $g = intval(substr($sArgb, -4, 2), 16);
    $r = intval(substr($sArgb, -6, 2), 16);

    // return an errary of integer values for ARGB value.
    return array($a, $r, $g, $b);
}

Similar to the ASP .NET version, the image handler must decode the link text from the query string. This is done using the decodeLinkText() function. Some example HTML for an image link is shown below:


<a class="stealthLink" href="javascript:spockBlam.Email.mailSend('cd0d8dbd3eed9a0d1e8d2ed96d1e4d4dddfa4dbd4e2d8d3d4d5ed92dedcd')">
<img alt="" src="EmSpockBlam.php?size=12&amp;clr=FFFFFFFF&amp;bkg=FF001A1C&amp;img=jpeg&amp;addr=0d1e8d2ed96d1e4d4dddfa4dbd4e2d8d3d4d5ed92dedcd" />
</a>

This uses the PHP GD graphics library. Interestingly enough, the PNG image format for these links rendered better in IE 8 than the PNG links generated using ASP .NET with the .NET GDI+ rendering. GD in PHP is a lot simpler than GDI+ and does not have all of the functionality, but if you want to do some heavy lifting for image processing in PHP, checkout the ImageMagick, Gmagick, and Cairo library bindings for PHP. More information for various sorts of image manipulation in PHP using these different libraries can be found in the on-line documentation at http://www.php.net/manual/en/book.image.php.

Download PDF
This entry was posted in JavaScript, PHP and tagged , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *