
![]() |
perkiset
Here is the image class that I use as a base for generating images on the fly. Note that it requires both GD and FreeType to be on the
machine before this will work. In the next post I will show usage:<? phpclass image { private $myHandle; private $myOutputMode; private $fontHandles; private $colorHandles; public $fadeHandles; private $currentColorHandle; private $currentFontSize; private $currentFontHandle; private $currentFontColor; public $handle; function __construct($width=-1, $height=-1, $backgroundColor='ffffff') { $this->fontHandles = array(); $this->colorHandles = array(); $this->fadeHandles = array(); $this->outputMode = 0; $this->myHandle = null; if (is_string($width) && ($height == -1)) { $fileName = $width; if (!file_exists($fileName)) { "Filename passed to image->construct does not exist or is inaccessible"; } $ptr = strrpos($fileName, '.'); $suffix = strtolower(substr($fileName, $ptr + 1, 4)); switch ($suffix) { case 'gif': $this->myHandle = imagecreatefromgif($fileName); break; case 'jpeg': case 'jpg': $this->myHandle = imagecreatefromjpeg($fileName); break; case 'png': $this->myHandle = imagecreatefrompng($fileName); break; default: die("Image class cannot be created from file with suffix '$suffix'"); } } else { if (($width==-1) || ($height==-1)) { die('You must pass both a height width to create an image object.'); } $this->myHandle = imagecreate($width, $height); } $red = hexdec(substr($backgroundColor, 0, 2)); $green = hexdec(substr($backgroundColor, 2, 2)); $blue = hexdec(substr($backgroundColor, 4, 2)); imagecolorallocate($this->myHandle, $red, $green, $blue); $this->handle = $this->myHandle; } function __destruct() { if (!$this->myHandle) { imagedestroy($this->myHandle); } } private function buildImage($fileName='') { switch ($this->myOutputMode) { case 0: if (strlen($fileName) > 0) { imagegif($this->myHandle, $filename); } else { imagegif($this->myHandle); } break; case 1: if (strlen($fileName) > 0) { imagejpeg($this->myHandle, $filename); } else { imagejpeg($this->myHandle); } break; case 2: if (strlen($fileName) > 0) { imagepng($this->myHandle, $filename); } else { imagepng($this->myHandle); } break; default: die('Unknown output mode "' . $this->myOutputMode . '"'); } } public function colorHandle($theHandle) { return $this->colorHandles[$theHandle]; } public function fadeValue($fadeName, $ptr) { return $this->fadeHandles[$fadeName][$ptr]; } public function generateFade($fadeName='NONAME', $fadeStart='######', $fadeEnd='######', $fadeSteps=0) { // Pass colors as "ae126f' - you do not need the # if ($fadeName == 'NONAME') { die('You must pass a fade name to image->generateFade as parameter 1'); } if ($fadeStart == '#######') { die('You must pass a fade start color value (hex) to image->generateFade as parameter 2'); } if ($fadeEnd == '#######') { die('You must pass a fade end color value (hex) to image->generateFade as parameter 3'); } if ($fadeSteps <= 0) { die('You must pass a non-zero positive value to image->generateFade as parameter 4'); } unset($this->fadeHandles[$fadeName]); $startRed = hexdec(substr($fadeStart, 0, 2)); $startGreen = hexdec(substr($fadeStart, 2, 2)); $startBlue = hexdec(substr($fadeStart, 4, 2)); $endRed = hexdec(substr($fadeEnd, 0, 2)); $endGreen = hexdec(substr($fadeEnd, 2, 2)); $endBlue = hexdec(substr($fadeEnd, 4, 2)); $deltaRed = $endRed - $startRed; $deltaGreen = $endGreen - $startGreen; $deltaBlue = $endBlue - $startBlue; $sineRed = ($deltaRed >= 0); $sineGreen = ($deltaGreen >= 0); $sineBlue = ($deltaBlue >= 0); $deltaRed = abs($deltaRed); $deltaGreen = abs($deltaGreen); $deltaBlue = abs($deltaBlue); $stepsRed = $deltaRed / $fadeSteps; $stepsGreen = $deltaGreen / $fadeSteps; $stepsBlue = $deltaBlue / $fadeSteps; $this->fadeHandles[$fadeName][0] = imagecolorallocate($this->myHandle, $startRed, $startGreen, $startBlue); $lastRed = $startRed; $lastGreen = $startGreen; $lastBlue = $startBlue; for ($i=1; $i<$fadeSteps; $i++) { $newRed = ($sineRed) ? ($lastRed + $stepsRed) : ($lastRed - $stepsRed); $newGreen = ($sineGreen) ? ($lastGreen + $stepsGreen) : ($lastGreen - $stepsGreen); $newBlue = ($sineBlue) ? ($lastBlue + $stepsBlue) : ($lastBlue - $stepsBlue); $thisRed = floor($newRed); $thisGreen = floor($newGreen); $thisBlue = floor($newBlue); if ( ($thisRed == floor($lastRed)) && ($thisGreen == floor($lastGreen)) && ($thisBlue == floor($lastBlue)) ) { $this->fadeHandles[$fadeName][$i] = $this->fadeHandles[$fadeName][$i - 1]; } else { $this->fadeHandles[$fadeName][$i] = imagecolorallocate($this->myHandle, $thisRed, $thisGreen, $thisBlue); } $lastRed = $newRed; $lastGreen = $newGreen; $lastBlue = $newBlue; } } public function getHeight() { return imagesy($this->myHandle); } public function getWidth() { return imagesx($this->myHandle); } public function importImage($theImage, $x=0, $y=0) { if (!is_a($theImage, 'image')) { die("image->importImage must be passed a reference to an image object"); } imagecopy($this->myHandle, $theImage->handle, $x, $y, 0, 0, imagesx($theImage->handle), imagesy($theImage->handle)); } public function outputMode($mode=-1) { if ($mode == -1) { die("You must pass a mode (0/1/2) to image->outputMode"); } switch ($mode) { case 0: case 1: case 2: $this->myOutputMode = $mode; break; default: die("You must pass a mode that is either 0, 1 or 2 to image->outputMode"); break; } } public function output() { list($usec, $sec) = explode(' ', microtime()); $theRand = rand(1000000000); $fileName = ((float)$usec + (float)$sec) . $theRand; $this->buildOutput("/tmp/$fileName"); $buffer = file_get_contents($fileName); unlink($fileName); return $buffer; } public function outputDirect() { switch($this->myOutputMode) { case 0: header('Content-type: image/gif'); break; case 1: header('Content-type: image/jpeg'); break; case 2: header('Content-type: image/png'); break; } $this->buildImage(); exit; } public function outputFile($fileName='') { if ($fileName == '') { die('You must pass a filename to image->fileOutput'); } $this->buildImage($fileName); } function rectangle($x0, $y0, $x1, $y1, $cHandle=-1) { if ($cHandle == -1) { $cHandle = $this->currentColorHandle; } imagerectangle($this->myHandle, $x0, $y0, $x1, $y1, $this->colorHandles[$cHandle]); } function rectangleFade($startColor, $endColor, $direction, $width, $height, $destX, $destY) { $tempImage = new image($width, $height); if ($direction) { // Horitzontal Fade $tempImage->generateFade('temp', $startColor, $endColor, $width); $fadeArr = &$tempImage->fadeHandles['temp']; for ($i=0; $i<$width; $i++) { imageline($tempImage->handle, $i, 0, $i, $height, $fadeArr[$i]); } imagecopy($this->myHandle, $tempImage->handle, $destX, $destY, 0, 0, $width, $height); } else { // Vertical Fade $tempImage->generateFade('temp', $startColor, $endColor, $height); $fadeArr = &$tempImage->fadeHandles['temp']; for ($i=0; $i<$height; $i++) { imageline($tempImage->handle, 0, $i, $width, $i, $fadeArr[$i]); } imagecopy($this->myHandle, $tempImage->handle, $destX, $destY, 0, 0, $width, $height); } } function registerColor($colorStr) { $red = hexdec(substr($colorStr, 0, 2)); $green = hexdec(substr($colorStr, 2, 2)); $blue = hexdec(substr($colorStr, 4, 2)); $this->colorHandles[] = imagecolorallocate($this->myHandle, $red, $green, $blue); $retVal = count($this->colorHandles) - 1; $this->currentColorHandle = $retVal; return $retVal; } function registerFont($fontPath) { if (!file_exists($fontPath)) { die("Font file '$fontPath' does not exist, or cannot be accessed (image->registerFont)"); } $this->fontHandles[] = $fontPath; return count($this->fontHandles) - 1; } public function setCurrentColor($theHandle = -1) { if (($theHandle < 0) || ($theHandle >= count($this->colorHandles))) { die('You must pass a valid handle to image->setColorHandle'); } $this->currentColorHandle = $theHandle; } public function setCurrentFont($theHandle) { if (($theHandle < 0) || ($theHandle >= count($this->fontHandles))) { die('You must pass a valid handle to image->setCurrentFont'); } $this->currentFontHandle = $theHandle; } public function setFontHandle($theHandle=-1) { if (($theHandle < 0) || ($theHandle >= count($this->fontHandles))) { die('You must pass a valid handle to image->setFontHandle'); } $this->currentFontHandle = $theHandle; } public function setFontSize($theSize=-1) { if ($theSize == -1) { die('You must pass a point size to image->setFontSize'); } $this->currentFontSize = $theSize; } public function simpleText($x, $y, $message, $cHandle=-1) { if ($cHandle == -1) { $cHandle = $this->currentColorHandle; } imagettftext($this->myHandle, $this->currentFontSize, 0, $x, $y, $this->colorHandles[$cHandle], $this->fontHandles[$this->currentFontHandle], $message); } public function vLine($hPos, $cHandle=-1, $vStart=-1, $vEnd = -1) { if ($vStart == -1) { $vStart = 0; } if ($vEnd == -1) { $vEnd = imagesy($this->myHandle); } if ($cHandle == -1) { $cHandle = $this->currentColorHandle; } imageline($this->myHandle, $hPos, $vStart, $hPos, $vEnd, $this->colorHandles[$cHandle]); } public function hLine($vPos, $cHandle=-1, $hStart=-1, $hEnd = -1) { if ($hStart == -1) { $hStart = 0; } if ($hEnd == -1) { $hEnd = imagesx($this->myHandle); } if ($cHandle == -1) { $cHandle = $this->currentColorHandle; } imageline($this->myHandle, $hStart, $vPos, $hEnd, $vPos, $this->colorHandles[$cHandle]); } } ?> perkiset
Here is a fragment of an image I created using the class above and the code below. This simulates an area chart with an interesting looking grid, left hand legend and imported images. I use similar stuff to this (although considerably less garrish) for my telemetry pages:
perkiset
This is the code that I used to create the image above. Note that it simply randomizes data points, imports a couple graphics that are on my
machine and also expects a font, "![]() Not also an interesting trick - I show the digits in the left handle legend in white at x-1 & y-1, x+1 & y-1, x-1 & y+1, x+1 & y+1 and then in dark black at x,y - this gives the effect of a white "stroke" around the letters so that it stands out over the blues. <? phperror_reporting(E_ALL); require_once('/www/sites/lib/classes/class.image. php');$sun = new image('/www/sites/graphics/telem_sun.gif'); $moon = new image('/www/sites/graphics/telem_moon.gif'); $main = new image(960, 300); $main->outputMode(2); $ht = $main->getHeight(); $wd = $main->getWidth(); $white = $main->registerColor('ffffff'); $black = $main->registerColor('000000'); $yellow = $main->registerColor('ffff00'); $gray = $main->registerColor('6a6a6a'); $denmark = $main->registerFont('/www/sites/lib/fonts/DENMARK.TTF'); $main->rectangleFade('09293c', '167cb8', true, 240, 300, 0, 0); $main->rectangleFade('167cb8', '09293c', true, 240, 300, 240, 0); $main->rectangleFade('09293c', '167cb8', true, 240, 300, 480, 0); $main->rectangleFade('167cb8', '09293c', true, 240, 300, 720, 0); // Draw the gray verticals... $i = -1; while (($i++ * 20) <= $wd) {$main->vLine($i * 20); } // Randomize my "data points" $traffic = array(); for ($i=0; $i<48; $i++) { $traffic[] = rand(75,300) - 50; } // Create my white polygon $chart = array(0, 0); for ($i=0; $i<48; $i++) { $chart[] = $i * 20; $chart[] = $traffic[$i]; } $chart[] = 960; $chart[] = 0; imagefilledpolygon($main->handle, $chart, 50, $main->colorHandle($white)); // Now the horizontal lines & legend... $i = -1; while (($i++ * 20) <= $ht) { $main->hLine($i * 20); } // Sun & moon... $main->importImage($moon, -40, 200); $main->importImage($sun, 200, 200); $main->importImage($moon, 440, 200); $main->importImage($sun, 680, 200); $main->importImage($moon, 920, 200); // Now the horizontal lines & legend... $i = -1; $main->setCurrentFont($denmark); $main->setFontSize(9); while (($i++ * 20) <= $ht) { $msg = (30 - $i) * 10; if ($msg > '160') { $main->simpleText(9, ($i * 20) - 2, $msg, $white); $main->simpleText(11, ($i * 20) - 2, $msg, $white); $main->simpleText(10, ($i * 20) - 1, $msg, $white); $main->simpleText(10, ($i * 20) - 3, $msg, $white); $main->simpleText(10, ($i * 20) - 2, $msg, $black); } } $main->outputDirect(); ?> thedarkness
Very cool Perk, I have a project which requires the generation of gantt style charts (actually a visual disply of employee's shifts0 this could be very handy.
Thanks, td perkiset
Dig it!
A favor - if you make a cool one, please post an example and some script... that'd be ginormously cool. /p thedarkness
Done, my "cool" may not be veryone elses "cool" though ;-)
I've got a class that reads mp3 headers and a few other bits and pieces that I wat to post, got to find them though :-P Cheers, td |

Thread Categories

![]() |
![]() |
Best of The Cache Home |
![]() |
![]() |
Search The Cache |
- Ajax
- Apache & mod_rewrite
- BlackHat SEO & Web Stuff
- C/++/#, Pascal etc.
- Database Stuff
- General & Non-Technical Discussion
- General programming, learning to code
- Javascript Discussions & Code
- Linux Related
- Mac, iPhone & OS-X Stuff
- Miscellaneous
- MS Windows Related
- PERL & Python Related
- PHP: Questions & Discussion
- PHP: Techniques, Classes & Examples
- Regular Expressions
- Uncategorized Threads