errmsg = ''; $this->error = false; $this->currentDimensions = array(); $this->newDimensions = array(); $this->fileName = $fileName; $this->imageMeta = array(); $this->percent = 100; $this->maxWidth = 0; $this->maxHeight = 0; //check to see if file exists if (!file_exists($this->fileName)) { $this->errmsg = 'File not found'; $this->error = true; } //check to see if file is readable elseif (!is_readable($this->fileName)) { $this->errmsg = 'File is not readable'; $this->error = true; } //if there are no errors, determine the file format if ($this->error == false) { //check if gif if (stristr(strtolower($this->fileName), '.gif')) $this->format = 'GIF'; //check if jpg elseif (stristr(strtolower($this->fileName), '.jpg') || stristr(strtolower($this->fileName), '.jpeg')) $this->format = 'JPG'; //check if png elseif (stristr(strtolower($this->fileName), '.png')) $this->format = 'PNG'; //unknown file format else { $this->errmsg = 'Unknown file format'; $this->error = true; } } //initialize resources if no errors if ($this->error == false) { switch ($this->format) { case 'GIF': $this->oldImage = ImageCreateFromGif($this->fileName); break; case 'JPG': $this->oldImage = ImageCreateFromJpeg($this->fileName); break; case 'PNG': $this->oldImage = ImageCreateFromPng($this->fileName); break; } $size = GetImageSize($this->fileName); $this->currentDimensions = array('width' => $size[0], 'height' => $size[1]); $this->newImage = $this->oldImage; //$this->gatherImageMeta(); } // if($this->error == true) { // return false; // } } /** * Must be called to free up allocated memory after all manipulations are done * */ function destruct() { if (is_resource($this->newImage)) @ImageDestroy($this->newImage); if (is_resource($this->oldImage)) @ImageDestroy($this->oldImage); if (is_resource($this->workingImage)) @ImageDestroy($this->workingImage); } /** * Returns the current width of the image * * @return int */ function getCurrentWidth() { return $this->currentDimensions['width']; } /** * Returns the current height of the image * * @return int */ function getCurrentHeight() { return $this->currentDimensions['height']; } /** * Calculates new image width * * @param int $width * @param int $height * * @return array */ function calcWidth($width, $height) { $newWp = (100 * $this->maxWidth) / $width; $newHeight = ($height * $newWp) / 100; return array('newWidth' => intval($this->maxWidth), 'newHeight' => intval($newHeight)); } /** * Calculates new image height * * @param int $width * @param int $height * * @return array */ function calcHeight($width, $height) { $newHp = (100 * $this->maxHeight) / $height; $newWidth = ($width * $newHp) / 100; return array('newWidth' => intval($newWidth), 'newHeight' => intval($this->maxHeight)); } /** * Calculates new image size based on percentage * * @param int $width * @param int $height * * @return array */ function calcPercent($width, $height) { $newWidth = ($width * $this->percent) / 100; $newHeight = ($height * $this->percent) / 100; return array('newWidth' => intval($newWidth), 'newHeight' => intval($newHeight)); } /** * Calculates new image size based on width and height, while constraining to maxWidth and maxHeight * * @param int $width * @param int $height */ function calcImageSize($width, $height) { $newSize = array('newWidth' => $width, 'newHeight' => $height); if ($this->maxWidth > 0) { $newSize = $this->calcWidth($width, $height); if ($this->maxHeight > 0 && $newSize['newHeight'] > $this->maxHeight) { $newSize = $this->calcHeight($newSize['newWidth'], $newSize['newHeight']); } //$this->newDimensions = $newSize; } if ($this->maxHeight > 0) { $newSize = $this->calcHeight($width, $height); if ($this->maxWidth > 0 && $newSize['newWidth'] > $this->maxWidth) { $newSize = $this->calcWidth($newSize['newWidth'], $newSize['newHeight']); } //$this->newDimensions = $newSize; } $this->newDimensions = $newSize; } /** * Calculates new image size based percentage * * @param int $width * @param int $height */ function calcImageSizePercent($width, $height) { if ($this->percent > 0) { $this->newDimensions = $this->calcPercent($width, $height); } } /** * Displays error image * */ function showErrorImage() { header('Content-type: image/png'); $errImg = ImageCreate(220, 25); $bgColor = imagecolorallocate($errImg, 0, 0, 0); $fgColor1 = imagecolorallocate($errImg, 255, 255, 255); $fgColor2 = imagecolorallocate($errImg, 255, 0, 0); imagestring($errImg, 3, 6, 6, 'Error:', $fgColor2); imagestring($errImg, 3, 55, 6, $this->errmsg, $fgColor1); imagepng($errImg); imagedestroy($errImg); } /** * Resizes image to maxWidth x maxHeight * * @param int $maxWidth * @param int $maxHeight */ function resize($maxWidth = 0, $maxHeight = 0) { $this->maxWidth = $maxWidth; $this->maxHeight = $maxHeight; $this->calcImageSize($this->currentDimensions['width'], $this->currentDimensions['height']); if (function_exists("ImageCreateTrueColor")) { $this->workingImage = ImageCreateTrueColor($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); } else { $this->workingImage = ImageCreate($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); } ImageCopyResampled($this->workingImage, $this->oldImage, 0, 0, 0, 0, $this->newDimensions['newWidth'], $this->newDimensions['newHeight'], $this->currentDimensions['width'], $this->currentDimensions['height']); $this->oldImage = $this->workingImage; $this->newImage = $this->workingImage; $this->currentDimensions['width'] = $this->newDimensions['newWidth']; $this->currentDimensions['height'] = $this->newDimensions['newHeight']; } /** * Resizes the image by $percent percent * * @param int $percent */ function resizePercent($percent = 0) { $this->percent = $percent; $this->calcImageSizePercent($this->currentDimensions['width'], $this->currentDimensions['height']); if (function_exists("ImageCreateTrueColor")) { $this->workingImage = ImageCreateTrueColor($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); } else { $this->workingImage = ImageCreate($this->newDimensions['newWidth'], $this->newDimensions['newHeight']); } ImageCopyResampled($this->workingImage, $this->oldImage, 0, 0, 0, 0, $this->newDimensions['newWidth'], $this->newDimensions['newHeight'], $this->currentDimensions['width'], $this->currentDimensions['height']); $this->oldImage = $this->workingImage; $this->newImage = $this->workingImage; $this->currentDimensions['width'] = $this->newDimensions['newWidth']; $this->currentDimensions['height'] = $this->newDimensions['newHeight']; } /** * Crops the image from calculated center in a square of $cropSize pixels * * @param int $cropSize */ function cropFromCenter($cropSize) { if ($cropSize > $this->currentDimensions['width']) $cropSize = $this->currentDimensions['width']; if ($cropSize > $this->currentDimensions['height']) $cropSize = $this->currentDimensions['height']; $cropX = intval(($this->currentDimensions['width'] - $cropSize) / 2); $cropY = intval(($this->currentDimensions['height'] - $cropSize) / 2); if (function_exists("ImageCreateTrueColor")) { $this->workingImage = ImageCreateTrueColor($cropSize, $cropSize); } else { $this->workingImage = ImageCreate($cropSize, $cropSize); } imagecopyresampled($this->workingImage, $this->oldImage, 0, 0, $cropX, $cropY, $cropSize, $cropSize, $cropSize, $cropSize); $this->oldImage = $this->workingImage; $this->newImage = $this->workingImage; $this->currentDimensions['width'] = $cropSize; $this->currentDimensions['height'] = $cropSize; } /** * Advanced cropping function that crops an image using $startX and $startY as the upper-left hand corner. * * @param int $startX * @param int $startY * @param int $width * @param int $height */ function crop($startX, $startY, $width, $height) { //make sure the cropped area is not greater than the size of the image if ($width > $this->currentDimensions['width']) $width = $this->currentDimensions['width']; if ($height > $this->currentDimensions['height']) $height = $this->currentDimensions['height']; //make sure not starting outside the image if (($startX + $width) > $this->currentDimensions['width']) $startX = ($this->currentDimensions['width'] - $width); if (($startY + $height) > $this->currentDimensions['height']) $startY = ($this->currentDimensions['height'] - $height); if ($startX < 0) $startX = 0; if ($startY < 0) $startY = 0; if (function_exists("ImageCreateTrueColor")) { $this->workingImage = ImageCreateTrueColor($width, $height); } else { $this->workingImage = ImageCreate($width, $height); } imagecopyresampled($this->workingImage, $this->oldImage, 0, 0, $startX, $startY, $width, $height, $width, $height); $this->oldImage = $this->workingImage; $this->newImage = $this->workingImage; $this->currentDimensions['width'] = $width; $this->currentDimensions['height'] = $height; } /** * Outputs the image to the screen, or saves to $name if supplied. Quality of JPEG images can be controlled with the $quality variable * * @param int $quality * @param string $name */ function show($quality = 100, $name = '') { switch ($this->format) { case 'GIF': if ($name != '') { ImageGif($this->newImage, $name); } else { header('Content-type: image/gif'); ImageGif($this->newImage); } break; case 'JPG': if ($name != '') { ImageJpeg($this->newImage, $name, $quality); } else { header('Content-type: image/jpeg'); ImageJpeg($this->newImage, '', $quality); } break; case 'PNG': if ($name != '') { ImagePng($this->newImage, $name); } else { header('Content-type: image/png'); ImagePng($this->newImage); } break; } } /** * Saves image as $name (can include file path), with quality of # percent if file is a jpeg * * @param string $name * @param int $quality */ function save($name, $quality = 100) { $this->show($quality, $name); } /** * Creates Apple-style reflection under image, optionally adding a border to main image * * @param int $percent * @param int $reflection * @param int $white * @param bool $border * @param string $borderColor */ function createReflection($percent, $reflection, $white, $border = true, $borderColor = '#a4a4a4') { $width = $this->currentDimensions['width']; $height = $this->currentDimensions['height']; $reflectionHeight = intval($height * ($reflection / 100)); $newHeight = $height + $reflectionHeight; $reflectedPart = $height * ($percent / 100); $this->workingImage = ImageCreateTrueColor($width, $newHeight); ImageAlphaBlending($this->workingImage, true); $colorToPaint = ImageColorAllocateAlpha($this->workingImage, 255, 255, 255, 0); ImageFilledRectangle($this->workingImage, 0, 0, $width, $newHeight, $colorToPaint); imagecopyresampled($this->workingImage, $this->newImage, 0, 0, 0, $reflectedPart, $width, $reflectionHeight, $width, ($height - $reflectedPart)); $this->imageFlipVertical(); imagecopy($this->workingImage, $this->newImage, 0, 0, 0, 0, $width, $height); imagealphablending($this->workingImage, true); for ($i = 0; $i < $reflectionHeight; $i++) { $colorToPaint = imagecolorallocatealpha($this->workingImage, 255, 255, 255, ($i / $reflectionHeight * -1 + 1) * $white); imagefilledrectangle($this->workingImage, 0, $height + $i, $width, $height + $i, $colorToPaint); } if ($border == true) { $rgb = $this->hex2rgb($borderColor, false); $colorToPaint = imagecolorallocate($this->workingImage, $rgb[0], $rgb[1], $rgb[2]); imageline($this->workingImage, 0, 0, $width, 0, $colorToPaint); //top line imageline($this->workingImage, 0, $height, $width, $height, $colorToPaint); //bottom line imageline($this->workingImage, 0, 0, 0, $height, $colorToPaint); //left line imageline($this->workingImage, $width - 1, 0, $width - 1, $height, $colorToPaint); //right line } $this->oldImage = $this->workingImage; $this->newImage = $this->workingImage; $this->currentDimensions['width'] = $width; $this->currentDimensions['height'] = $newHeight; } /** * Inverts working image, used by reflection function * * @access private */ function imageFlipVertical() { $x_i = imagesx($this->workingImage); $y_i = imagesy($this->workingImage); for ($x = 0; $x < $x_i; $x++) { for ($y = 0; $y < $y_i; $y++) { imagecopy($this->workingImage, $this->workingImage, $x, $y_i - $y - 1, $x, $y, 1, 1); } } } /** * Converts hexidecimal color value to rgb values and returns as array/string * * @param string $hex * @param bool $asString * * @return array|string */ function hex2rgb($hex, $asString = false) { // strip off any leading # if (0 === strpos($hex, '#')) { $hex = substr($hex, 1); } else if (0 === strpos($hex, '&H')) { $hex = substr($hex, 2); } // break into hex 3-tuple $cutpoint = ceil(strlen($hex) / 2) - 1; $rgb = explode(':', wordwrap($hex, $cutpoint, ':', $cutpoint), 3); // convert each tuple to decimal $rgb[0] = (isset($rgb[0]) ? hexdec($rgb[0]) : 0); $rgb[1] = (isset($rgb[1]) ? hexdec($rgb[1]) : 0); $rgb[2] = (isset($rgb[2]) ? hexdec($rgb[2]) : 0); return ($asString ? "{$rgb[0]} {$rgb[1]} {$rgb[2]}" : $rgb); } /** * Reads selected exif meta data from jpg images and populates $this->imageMeta with appropriate values if found * */ function gatherImageMeta() { //only attempt to retrieve info if exif exists if (function_exists("exif_read_data") && $this->format == 'JPG') { $imageData = exif_read_data($this->fileName); if (isset($imageData['Make'])) $this->imageMeta['make'] = ucwords(strtolower($imageData['Make'])); if (isset($imageData['Model'])) $this->imageMeta['model'] = $imageData['Model']; if (isset($imageData['COMPUTED']['ApertureFNumber'])) { $this->imageMeta['aperture'] = $imageData['COMPUTED']['ApertureFNumber']; $this->imageMeta['aperture'] = str_replace('/', '', $this->imageMeta['aperture']); } if (isset($imageData['ExposureTime'])) { $exposure = explode('/', $imageData['ExposureTime']); $exposure = round($exposure[1] / $exposure[0], -1); $this->imageMeta['exposure'] = '1/' . $exposure . ' second'; } if (isset($imageData['Flash'])) { if ($imageData['Flash'] > 0) { $this->imageMeta['flash'] = 'Yes'; } else { $this->imageMeta['flash'] = 'No'; } } if (isset($imageData['FocalLength'])) { $focus = explode('/', $imageData['FocalLength']); $this->imageMeta['focalLength'] = round($focus[0] / $focus[1], 2) . ' mm'; } if (isset($imageData['DateTime'])) { $date = $imageData['DateTime']; $date = explode(' ', $date); $date = str_replace(':', '-', $date[0]) . ' ' . $date[1]; $this->imageMeta['dateTaken'] = date('m/d/Y g:i A', strtotime($date)); } } } /** * Rotates image either 90 degrees clockwise or counter-clockwise * * @param string $direction */ function rotateImage($direction = 'CW') { if ($direction == 'CW') { $this->workingImage = imagerotate($this->workingImage, -90, 0); } else { $this->workingImage = imagerotate($this->workingImage, 90, 0); } $newWidth = $this->currentDimensions['height']; $newHeight = $this->currentDimensions['width']; $this->oldImage = $this->workingImage; $this->newImage = $this->workingImage; $this->currentDimensions['width'] = $newWidth; $this->currentDimensions['height'] = $newHeight; } } ?>