outputJpg(); //-------------------------------------------------- // Load two images $imageSub = new image('2.gif'); $image = new image('1.jpg'); $image->addImage($imageSub, 10, 123); $image->outputGif(); //-------------------------------------------------- // End of example setup ***************************************************/ define('IMAGE_LOAD_SUCCESS', 0); define('IMAGE_LOAD_ERR_GONE', 1); define('IMAGE_LOAD_ERR_SIZE', 2); define('IMAGE_LOAD_ERR_READ', 3); define('IMAGE_ADD_IMAGE_TILE_TOP_LEFT', 0); define('IMAGE_ADD_IMAGE_TILE_CENTER', 1); class image { function image($filePath = NULL) { $this->imageWidth = NULL; $this->imageHeight = NULL; $this->imageType = NULL; $this->imageRef = NULL; if ($filePath !== NULL) { $this->loadFromFile($filePath); } } function createImage($width, $height, $bgRed = 0, $bgGreen = 0, $bgBlue = 0) { //-------------------------------------------------- // Create $this->imageRef = imagecreatetruecolor($width, $height); //-------------------------------------------------- // Background $bg = imagecolorallocate($this->imageRef, $bgRed, $bgGreen, $bgBlue); imagefill($this->imageRef, 0, 0, $bg); } function _loadImage($image) { //-------------------------------------------------- // Return $return = array(); //-------------------------------------------------- // If an image object was passed into this function if (is_object($image) && get_class($image) == 'image') { if (!$image->imageRef) { return IMAGE_LOAD_ERR_READ; } $return['ref'] = $image->imageRef; $return['width'] = $image->imageWidth; $return['height'] = $image->imageHeight; $return['type'] = $image->imageType; return $return; } //-------------------------------------------------- // If not a file if (substr($image, 0, 7) != 'http://' && (!is_file($image) || !is_readable($image))) { return IMAGE_LOAD_ERR_GONE; } //-------------------------------------------------- // Image dimensions $dimensions = getimagesize($image); if ($dimensions !== false) { $return['width'] = $dimensions[0]; $return['height'] = $dimensions[1]; $return['type'] = $dimensions[2]; } else { return IMAGE_LOAD_ERR_SIZE; } //-------------------------------------------------- // Reference if ($return['type'] == IMAGETYPE_JPEG) { $return['ref'] = imagecreatefromjpeg($image); } else if ($return['type'] == IMAGETYPE_GIF) { $return['ref'] = imagecreatefromgif($image); } else if ($return['type'] == IMAGETYPE_PNG) { $return['ref'] = imagecreatefrompng($image); } else { return IMAGE_LOAD_ERR_READ; } //-------------------------------------------------- // Return return $return; } function loadFromFile($filePath) { $return = $this->_loadImage($filePath); if (!is_array($return)) { return $return; } $this->imageWidth = $return['width']; $this->imageHeight = $return['height']; $this->imageType = $return['type']; $this->imageRef = $return['ref']; return IMAGE_LOAD_SUCCESS; } function addImage($image, $left = 0, $top = 0, $width = NULL, $height = NULL) { if ($this->imageRef) { $return = $this->_loadImage($image); if (!is_array($return)) { return $return; } if ($width === NULL) $width = $return['width']; if ($height === NULL) $height = $return['height']; imagecopyresampled($this->imageRef, $return['ref'], $left, $top, 0, 0, $width, $height, $return['width'], $return['height']); return IMAGE_LOAD_SUCCESS; } } function addImageTileToArea($image, $areaWidth, $areaHeight, $areaLeft, $areaTop, $style = IMAGE_ADD_IMAGE_TILE_CENTER) { if ($this->imageRef) { //-------------------------------------------------- // Load $tile = $this->_loadImage($image); if (!is_array($tile)) { return $tile; } //-------------------------------------------------- // Tile repeat count $repeatL = ceil($areaWidth / $tile['width']); $repeatT = ceil($areaHeight / $tile['height']); //-------------------------------------------------- // Offset if ($style == IMAGE_ADD_IMAGE_TILE_TOP_LEFT) { $offsetLeft = 0; $offsetTop = 0; } else { $offsetLeft = (0 - round((($repeatL * $tile['width']) - $areaWidth) / 2)); $offsetTop = (0 - round((($repeatT * $tile['height']) - $areaHeight) / 2)); } //-------------------------------------------------- // Apply tiles for ($l = 0; $l < $repeatL; $l++) { for ($t = 0; $t < $repeatT; $t++) { //-------------------------------------------------- // Grid position $destLeft = ($tile['width'] * $l); $destTop = ($tile['height'] * $t); //-------------------------------------------------- // Which part of the tile to copy - cuts off the // left and top sides $srcLeft = ($l == 0 ? (0 - $offsetLeft) : 0); $srcTop = ($t == 0 ? (0 - $offsetTop) : 0); //-------------------------------------------------- // Size of the tile area to copy - cuts off the // right and bottom sides //-------------------------------------------------- // Width $srcWidth = ($areaWidth - $destLeft) - $offsetLeft; // Double negative, add offsetLeft if ($srcWidth > $tile['width']) { $srcWidth = $tile['width']; // Not too much } $srcWidth -= $srcLeft; // If left-side is cut, don't address too much //-------------------------------------------------- // Height $srcHeight = ($areaHeight - $destTop) - $offsetTop; // Double negative, add offsetTop if ($srcHeight > $tile['height']) { $srcHeight = $tile['height']; // Not too much } $srcHeight -= $srcTop; // If top-side is cut, don't address too much //-------------------------------------------------- // Apply the skew to the grid position - where // the 'offset' and 'src' are the same on the // left column or top row... otherwise its only // the 'offset' which is applied from these two. $destLeft += $areaLeft + ($offsetLeft + $srcLeft); $destTop += $areaTop + ($offsetTop + $srcTop); //-------------------------------------------------- // Copy the tile onto the image, keeping 1:1 ratio imagecopyresampled($this->imageRef, $tile['ref'], $destLeft, $destTop, $srcLeft, $srcTop, $srcWidth, $srcHeight, $srcWidth, $srcHeight); } } //-------------------------------------------------- // Success return IMAGE_LOAD_SUCCESS; } } function addImageTile($image, $style = IMAGE_ADD_IMAGE_TILE_CENTER) { $this->addImageTileToArea($image, $this->imageWidth, $this->imageHeight, 0, 0, $style); } function centerToBox($boxWidth, $boxHeight, $bgRed = 0, $bgGreen = 0, $bgBlue = 0, $scale = true) { if ($this->imageRef) { //-------------------------------------------------- // Create the canvas $newImage = imagecreatetruecolor($boxWidth, $boxHeight); $background = imagecolorallocate($newImage, $bgRed, $bgGreen, $bgBlue); imagefill($newImage, 0, 0, $background); //-------------------------------------------------- // Configure the centre area $width = $this->imageWidth; $height = $this->imageHeight; if ($scale) { if ($width > $boxWidth) { $height = ceil($boxWidth * ($height / $width)); $width = $boxWidth; } if ($height > $boxHeight) { $width = ceil($boxHeight * ($width / $height)); $height = $boxHeight; } } $top = round(($boxHeight / 2) - ($height / 2)); $left = round(($boxWidth / 2) - ($width / 2)); imagecopyresampled($newImage, $this->imageRef, $left, $top, 0, 0, $width, $height, $this->imageWidth, $this->imageHeight); //-------------------------------------------------- // Replace the image $this->imageRef = $newImage; } } function cutToBox($boxWidth, $boxHeight, $bgRed = 0, $bgGreen = 0, $bgBlue = 0) { $this->centerToBox($boxWidth, $boxHeight, $bgRed, $bgGreen, $bgBlue, false); } function sizeAndCutToBox($boxWidth, $boxHeight, $bgRed = 0, $bgGreen = 0, $bgBlue = 0) { if ($this->imageRef) { //-------------------------------------------------- // Create the canvas $newImage = imagecreatetruecolor($boxWidth, $boxHeight); $background = imagecolorallocate($newImage, $bgRed, $bgGreen, $bgBlue); imagefill($newImage, 0, 0, $background); //-------------------------------------------------- // Configure the centre area if ($this->imageWidth <= $boxWidth && $this->imageHeight <= $boxHeight) { $newWidth = $this->imageWidth; $newHeight = $this->imageHeight; } else { // This isn't right... its possible for images // to be stretched to a larger size. $newHeight = ceil($boxWidth * ($this->imageHeight / $this->imageWidth)); $newWidth = $boxWidth; if ($newHeight < $boxHeight) { $newWidth = ceil($boxHeight * ($this->imageWidth / $this->imageHeight)); $newHeight = $boxHeight; } } $top = round(($boxHeight / 2) - ($newHeight / 2)); $left = round(($boxWidth / 2) - ($newWidth / 2)); imagecopyresampled($newImage, $this->imageRef, $left, $top, 0, 0, $newWidth, $newHeight, $this->imageWidth, $this->imageHeight); //-------------------------------------------------- // Replace the image $this->imageRef = $newImage; } } function maxSize($maxWidth, $maxHeight) { if ($this->imageRef && ($this->imageWidth > $maxWidth || $this->imageHeight > $maxHeight)) { //-------------------------------------------------- // Dimensions $newWidth = $this->imageWidth; $newHeight = $this->imageHeight; if ($newWidth > $maxWidth) { $newHeight = (round($maxWidth * ($newHeight / $newWidth))); $newWidth = $maxWidth; } if ($newHeight > $maxHeight) { $newWidth = (round($maxHeight * ($newWidth / $newHeight))); $newHeight = $maxHeight; } //-------------------------------------------------- // Size $newImage = imagecreatetruecolor($newWidth, $newHeight); imagealphablending($newImage, false); imagecopyresampled($newImage, $this->imageRef, 0, 0, 0, 0, $newWidth, $newHeight, $this->imageWidth, $this->imageHeight); //-------------------------------------------------- // Store $this->imageRef = $newImage; $this->imageWidth = $newWidth; $this->imageHeight = $newHeight; } } function forceSize($width, $height) { if ($this->imageRef) { $newImage = imagecreatetruecolor($width, $height); imagealphablending($newImage, false); imagecopyresampled($newImage, $this->imageRef, 0, 0, 0, 0, $width, $height, $this->imageWidth, $this->imageHeight); $this->imageRef = $newImage; $this->imageWidth = $width; $this->imageHeight = $height; } } function cropSize($width, $height, $left = 0, $top = 0) { if ($this->imageRef) { $newImage = imagecreatetruecolor($width, $height); imagealphablending($newImage, false); imagecopyresampled($newImage, $this->imageRef, 0, 0, $left, $top, $width, $height, $width, $height); $this->imageRef = $newImage; $this->imageWidth = $width; $this->imageHeight = $height; } } function getWidth() { return $this->imageWidth; } function getHeight() { return $this->imageHeight; } function getType() { return $this->imageType; } function getRef() { return $this->imageRef; } function outputPng($compression = 0) { if ($this->imageRef) { header('Content-type: image/png'); imagepng($this->imageRef, NULL, $compression); } } function outputGif() { if ($this->imageRef) { header('Content-type: image/gif'); imagegif($this->imageRef); } } function outputJpg($quality = 80) { if ($this->imageRef) { header('Content-type: image/jpeg'); imagejpeg($this->imageRef, NULL, $quality); } } function savePng($filePath, $compression = 0) { if ($this->imageRef) { imagepng($this->imageRef, $filePath, $compression); @chmod($filePath, 0666); } } function saveGif($filePath) { if ($this->imageRef) { imagegif($this->imageRef, $filePath); @chmod($filePath, 0666); } } function saveJpg($filePath, $quality = 80) { if ($this->imageRef) { imagejpeg($this->imageRef, $filePath, $quality); @chmod($filePath, 0666); } } function saveTiles($numTilesWide, $numTilesHigh, $fileNamePrefix, $fileNameExt = 'jpg', $tileWidth = 256, $tileHeight = 256, $bgRed = 0, $bgGreen = 0, $bgBlue = 0, $quality = NULL) { if ($this->imageRef) { //-------------------------------------------------- // Create the canvas //-------------------------------------------------- // Start $canvasWidth = ($numTilesWide * $tileWidth); $canvasHeight = ($numTilesHigh * $tileHeight); $canvas = imagecreatetruecolor($canvasWidth, $canvasHeight); //-------------------------------------------------- // Background $background = imagecolorallocate($canvas, $bgRed, $bgGreen, $bgBlue); imagefill($canvas, 0, 0, $background); //-------------------------------------------------- // Add image if ($this->imageWidth > $this->imageHeight) { $canvasZoomMaxLevel = ceil(log(ceil($this->imageWidth / $tileWidth), 2)); } else { $canvasZoomMaxLevel = ceil(log(ceil($this->imageHeight / $tileHeight), 2)); } $canvasZoomMaxSizeWidth = (intval(pow(2, $canvasZoomMaxLevel)) * $tileWidth); $canvasZoomMaxSizeHeight = (intval(pow(2, $canvasZoomMaxLevel)) * $tileHeight); $width = (($this->imageWidth / $canvasZoomMaxSizeWidth) * $canvasWidth); $height = (($this->imageHeight / $canvasZoomMaxSizeHeight) * $canvasHeight); $offsetLeft = (($canvasWidth / 2) - ($width / 2)); $offsetTop = (($canvasHeight / 2) - ($height / 2)); imagecopyresampled($canvas, $this->imageRef, $offsetLeft, $offsetTop, 0, 0, $width, $height, $this->imageWidth, $this->imageHeight); //-------------------------------------------------- // Save the image parts for ($x = 0; $x < $numTilesWide; $x++) { for ($y = 0; $y < $numTilesHigh; $y++) { $tile = imagecreatetruecolor($tileWidth, $tileHeight); imagecopyresampled($tile, $canvas, 0, 0, ($x * $tileWidth), ($y * $tileWidth), $tileWidth, $tileHeight, $tileWidth, $tileHeight); $filePath = $fileNamePrefix . $x . '-' . $y . '.' . $fileNameExt; if ($quality) { if ($fileNameExt == 'png') imagepng($tile, $filePath, $quality); if ($fileNameExt == 'jpg') imagejpeg($tile, $filePath, $quality); } else { if ($fileNameExt == 'png') imagepng($tile, $filePath); if ($fileNameExt == 'gif') imagegif($tile, $filePath); if ($fileNameExt == 'jpg') imagejpeg($tile, $filePath); } @chmod($filePath, 0666); imagedestroy($tile); } } //-------------------------------------------------- // Cleanup imagedestroy($canvas); } } function destroy() { if ($this->imageRef) { imagedestroy($this->imageRef); $this->imageRef = NULL; } } } //-------------------------------------------------- // Copyright (c) 2006, Craig Francis All rights // reserved. // // Redistribution and use in source and binary forms, // with or without modification, are permitted provided // that the following conditions are met: // // * Redistributions of source code must retain the // above copyright notice, this list of // conditions and the following disclaimer. // * Redistributions in binary form must reproduce // the above copyright notice, this list of // conditions and the following disclaimer in the // documentation and/or other materials provided // with the distribution. // * Neither the name of the author nor the names // of its contributors may be used to endorse or // promote products derived from this software // without specific prior written permission. // // This software is provided by the copyright holders // and contributors "as is" and any express or implied // warranties, including, but not limited to, the // implied warranties of merchantability and fitness // for a particular purpose are disclaimed. In no event // shall the copyright owner or contributors be liable // for any direct, indirect, incidental, special, // exemplary, or consequential damages (including, but // not limited to, procurement of substitute goods or // services; loss of use, data, or profits; or business // interruption) however caused and on any theory of // liability, whether in contract, strict liability, or // tort (including negligence or otherwise) arising in // any way out of the use of this software, even if // advised of the possibility of such damage. //-------------------------------------------------- ?>