PHP Demo Application - Source Code
/Framework/Model/Libraries/Image.php
<?php
/**
* Script Contents: Apeel_Framework_Model_Libraries_Image Class Library
* @package Apeel_Framework_Model_Libraries
*/
/**
* Library to provide Image formatting / outputting.
*
* @package Apeel_Framework_Model_Libraries
* @version 1.1.0
* @author John W. King (email: contact@apeelframework.net)
* @copyright City Business Logic Limited 2001-2011
* @license Dual MIT / GNU Lesser General Public License Version 3
*/
class Apeel_Framework_Model_Libraries_Image {
/**
* Format and Output the specified image.
*
* $filename should not contain path details as images should be stored in
* the folder referenced by APEEL_UPLOAD_FOLDER.
*
* $noImage is the image to display if either $filename is empty or the
* specified image does not exist (e.g. in an estate agents portal
* there may be a standard "coming soon" image until the get around to
* photographing the property. )
*
* $resizeMode is an integer value corresponding to the available resize
* constants defined in the file library. They are:
*
* Apeel_Framework_Model_Libraries_File::$direct
* No resizing.
*
* Apeel_Framework_Model_Libraries_File::$resize
* Resize to exact given dimensions.
*
* Apeel_Framework_Model_Libraries_File::$resizeConstrain
* Resize to fit within dimensions - i.e. scale image down until both axis fit
* within the dimensions given.
*
* Apeel_Framework_Model_Libraries_File::$resizeConstrainBorder
* Resize to fit within dimensions - like $resizeConstrain - but pad with
* border.
*
* The Red/Green/Blue values are only applicable when mode is
* $resizeConstrainBorder and they define the color of the border.
*
* @param string $filename
* @param string $noImage
* @param integer $resizeMode
* @param integer $width
* @param integer $height
* @param integer $red
* @param integer $green
* @param integer $blue
* @return void
*/
public function outputImage(
$filename,
$noImage,
$resizeMode,
$width = 0,
$height = 0,
$red = -1,
$green = -1,
$blue = -1
) {
if ($filename == '') {
$filename = $noImage;
}
$fullFilename = Apeel_Framework_Model_Libraries_File::getFullFilePath($filename);
if (!$fullFilename) {
$filename = $noImage;
$fullFilename = Apeel_Framework_Model_Libraries_File::getFullFilePath($filename);
}
if ($fullFilename) {
$fileInfo = Apeel_Framework_Model_Libraries_File::getFileInfo(Apeel_Framework_Model_Libraries_File::getFileExtension($filename));
$mimeType = $fileInfo['mimeType'];
$isImage = $fileInfo['isImage'];
if ($isImage) {
if ($resizeMode == Apeel_Framework_Model_Libraries_File::$direct) {
$rawFile = @fopen($fullFilename, 'rb');
} else{
$rawFile = $this->resizeImage($fullFilename, $mimeType, $resizeMode, $width, $height, $red, $green, $blue);
}
if ($rawFile) {
header('Content-type: ' . $mimeType);
fpassthru($rawFile);
ob_flush();
exit;
}
}
}
}
/**
* Performs generic processing to resize an image to fit within the given
* dimensions. It is called by outputImage(...) method, and uses
* resizeGif(...), resizeJpg(...) and resizePng(...) to perform format
* specific processing.
*
* $filename should not contain path details as images should be stored in
* the folder referenced by APEEL_UPLOAD_FOLDER.
*
* $resizeMode is an integer value corresponding to the available resize
* constants defined in the file library. They are:
*
* Apeel_Framework_Model_Libraries_File::$direct
* No resizing.
*
* Apeel_Framework_Model_Libraries_File::$resize
* Resize to exact given dimensions.
*
* Apeel_Framework_Model_Libraries_File::$resizeConstrain
* Resize to fit within dimensions - i.e. scale image down until both axis fit
* within the dimensions given.
*
* Apeel_Framework_Model_Libraries_File::$resizeConstrainBorder
* Resize to fit within dimensions - like $resizeConstrain - but pad with
* border.
*
* The Red/Green/Blue values are only applicable when mode is
* $resizeConstrainBorder and they define the color of the border.
*
* The method tries to increase the memory limit to help ensure it does not
* run out of memory whilst processing. Not all hosts/administrators will
* enable this functionality.
*
* @param string $filename
* @param string $mimeType
* @param integer $resizeMode
* @param integer $newWidth
* @param integer $newHeight
* @param integer $red
* @param integer $green
* @param integer $blue
* @return Image
*/
private function resizeImage(
$filename,
$mimeType,
$resizeMode,
$newWidth,
$newHeight,
$red = -1,
$green = -1,
$blue = -1
) {
$oldLimit = @ini_set("memory_limit", "64M");
$imageInfo = @getimagesize($filename);
if (count($imageInfo) >= 2) {
$oldWidth = $imageInfo[0];
$oldHeight = $imageInfo[1];
$offsetWidth = 0;
$offsetHeight = 0;
if (($resizeMode == Apeel_Framework_Model_Libraries_File::$resizeConstrain) ||
($resizeMode == Apeel_Framework_Model_Libraries_File::$resizeConstrainBorder)) {
$ratio = min($newWidth / $oldWidth, $newHeight / $oldHeight);
$targetNewWidth = $newWidth;
$targetNewHeight = $newHeight;
if (($newWidth > $oldWidth) && ($newHeight > $oldHeight)) {
$newWidth = $oldWidth;
$newHeight = $oldHeight;
} else {
$newWidth = round($ratio * $oldWidth);
$newHeight = round($ratio * $oldHeight);
}
if ($resizeMode == Apeel_Framework_Model_Libraries_File::$resizeConstrainBorder) {
$offsetWidth = round(($targetNewWidth - $newWidth) / 2);
$offsetHeight = round(($targetNewHeight - $newHeight) / 2);
}
}
if ($mimeType == 'image/gif') {
return $this->resizeGif($filename, $newWidth, $newHeight, $oldWidth, $oldHeight, $offsetWidth, $offsetHeight, $red, $green, $blue);
} else if ($mimeType == 'image/jpeg') {
return $this->resizeJpg($filename, $newWidth, $newHeight, $oldWidth, $oldHeight, $offsetWidth, $offsetHeight, $red, $green, $blue);
} else if ($mimeType == 'image/png') {
return $this->resizePng($filename, $newWidth, $newHeight, $oldWidth, $oldHeight, $offsetWidth, $offsetHeight, $red, $green, $blue);
}
}
@ini_set("memory_limit", $old_limit);
}
/**
* Performs specific processing to resize a GIF format image to fit within
* the given dimensions. It is called by outputImage(...) method.
*
* $filename should not contain path details as images should be stored in
* the folder referenced by APEEL_UPLOAD_FOLDER.
*
* $newWidth/$newHeight are the dimensions of the new image.
*
* $oldWidth/$oldHeight are the original dimensions.
*
* $offsetWidth/$offsetHeight specify where the image should appear within
* it's border (if there is one).
*
* The Red/Green/Blue values are only applicable when mode is
* $resizeConstrainBorder and they define the color of the border.
*
* @param string $filename
* @param integer $newWidth
* @param integer $newHeight
* @param integer $oldWidth
* @param integer $oldHeight
* @param integer $offsetWidth
* @param integer $offsetHeight
* @param integer $red
* @param integer $green
* @param integer $blue
* @return Image
*/
private function resizeGif(
$filename,
$newWidth,
$newHeight,
$oldWidth,
$oldHeight,
$offsetWidth,
$offsetHeight,
$red = -1,
$green = -1,
$blue = -1
) {
$newImage = @imagecreatetruecolor($newWidth + ($offsetWidth * 2), $newHeight + ($offsetHeight * 2));
if ($red != -1) {
$backgroundColour = ImageColorAllocate($newImage, $red, $green, $blue);
@imagefill($newImage, 0, 0, $backgroundColour);
}
$rawImageData = @imagecreatefromgif($filename);
$totalColours = @imagecolorstotal($rawImageData);
for($index = 0; $index < $totalColours; $index++) {
$colour = @imagecolorsforindex($rawImageData, $index);
if($colour['alpha'] == 127) {
$transparentColour = @imageColorAllocate(
$newImage,
$colour['red'],
$colour['green'],
$colour['blue']
);
@imagecolortransparent($newImage, $transparentColour);
} else {
@imagecolorset(
$newImage,
$index,
$colour['red'],
$colour['green'],
$colour['blue']
);
}
}
@imagecopyresized(
$newImage,
$rawImageData,
$offsetWidth,
$offsetHeight,
0,
0,
$newWidth,
$newHeight,
$oldWidth,
$oldHeight
);
$newImage = @imagepng($newImage, null, 0, PNG_NO_FILTER);
return $newImage;
}
/**
* Performs specific processing to resize a JPEG format image to fit within
* the given dimensions. It is called by outputImage(...) method.
*
* $filename should not contain path details as images should be stored in
* the folder referenced by APEEL_UPLOAD_FOLDER.
*
* $newWidth/$newHeight are the dimensions of the new image.
*
* $oldWidth/$oldHeight are the original dimensions.
*
* $offsetWidth/$offsetHeight specify where the image should appear within
* it's border (if there is one).
*
* The Red/Green/Blue values are only applicable when mode is
* $resizeConstrainBorder and they define the color of the border.
*
* $quality tells the method what quality ratio (0..100 where 0 is worst,
* and 100 is best, 75 is typical) the image should be saved at.
*
* @param string $filename
* @param integer $newWidth
* @param integer $newHeight
* @param integer $oldWidth
* @param integer $oldHeight
* @param integer $offsetWidth
* @param integer $offsetHeight
* @param integer $red
* @param integer $green
* @param integer $blue
* @param mixed $quality
* @return Image
*/
private function resizeJpg($filename, $newWidth, $newHeight, $oldWidth, $oldHeight, $offsetWidth, $offsetHeight, $red = -1, $green = -1, $blue = -1, $quality = 100) {
$newImage = @imagecreatetruecolor($newWidth + ($offsetWidth * 2), $newHeight + ($offsetHeight * 2));
if ($red != -1) {
$backgroundColour = ImageColorAllocate($newImage, $red, $green, $blue);
@imagefill($newImage, 0, 0, $backgroundColour);
}
$rawImageData = @imagecreatefromjpeg($filename);
@imagecopyresized(
$newImage,
$rawImageData,
$offsetWidth,
$offsetHeight,
0,
0,
$newWidth,
$newHeight,
$oldWidth,
$oldHeight
);
$newImage = @imagepng($newImage, null, 0, PNG_NO_FILTER);
return $newImage;
}
/**
* Performs specific processing to resize a PNG format image to fit within
* the given dimensions. It is called by outputImage(...) method.
*
* $filename should not contain path details as images should be stored in
* the folder referenced by APEEL_UPLOAD_FOLDER.
*
* $newWidth/$newHeight are the dimensions of the new image.
*
* $oldWidth/$oldHeight are the original dimensions.
*
* $offsetWidth/$offsetHeight specify where the image should appear within
* it's border (if there is one).
*
* The Red/Green/Blue values are only applicable when mode is
* $resizeConstrainBorder and they define the color of the border.
*
* $quality tells the method what quality ratio (0..100 where 0 is worst,
* and 100 is best, 75 is typical) the image should be saved at.
*
* @param string $filename
* @param integer $newWidth
* @param integer $newHeight
* @param integer $oldWidth
* @param integer $oldHeight
* @param integer $offsetWidth
* @param integer $offsetHeight
* @param integer $red
* @param integer $green
* @param integer $blue
* @return Image
*/
private function resizePng($filename, $newWidth, $newHeight, $oldWidth, $oldHeight, $offsetWidth, $offsetHeight, $red = -1, $green = -1, $blue = -1) {
$newImage = @imagecreatetruecolor($newWidth + ($offsetWidth * 2), $newHeight + ($offsetHeight * 2));
if ($red != -1) {
$backgroundColour = ImageColorAllocate($newImage, $red, $green, $blue);
@imagefill($newImage, 0, 0, $backgroundColour);
}
@imagealphablending($newImage, false);
$rawImageData = @imagecreatefrompng($filename);
@imagecopyresized(
$newImage,
$rawImageData,
$offsetWidth,
$offsetHeight,
0,
0,
$newWidth,
$newHeight,
$oldWidth,
$oldHeight
);
@imagesavealpha($newImage, true);
$newImage = imagepng($newImage, null, 0, PNG_NO_FILTER);
return $newImage;
}
}
?>