PHP Classes

File: includes/Thumbnail.php

Recommend this page to a friend!
  Classes of Roman Krivosheev   Simple thumbnail   includes/Thumbnail.php   Download  
File: includes/Thumbnail.php
Role: Class source
Content type: text/plain
Description: Thumbnail class
Class: Simple thumbnail
Create thumbnails by cropping or resizing an image
Author: By
Last change: Add method croping and transparent scale PNG
Date: 12 years ago
Size: 17,254 bytes
 

Contents

Class file image Download
<?php /** * Project: Thumbnail simple resize: lite resize and crop image * File: Thumbnail.php * * @copyright 2012 Roman Krivosheev, Personal. * @author Roman Krivosheev <web.volga@gmail.com> * @author Roman Krivosheev (icq: 446666000) * @package Thumbnail * @version 3.5.0 * * * include 'includes/Thumbnail.php'; * $filename = '0001.jpg'; * $options = array( * 'type' => IMAGETYPE_JPEG, * 'width' => 150, * 'height' => 150, * 'method' => THUMBNAIL_METHOD_SCALE_MAX, * 'coord_x1' => 0, * 'coord_y1' => 0, * 'coord_x2' => 0, * 'coord_y2' => 0, * 'percent' => 0, * 'halign' => THUMBNAIL_ALIGN_CENTER, * 'valign' => THUMBNAIL_ALIGN_CENTER, * 'corner' => 0, * 'corcolor' => 'FFFFFF', * 'cortransparent' => 0, * 'mark' => 0, * ); * * Watermark position (#array option 'mark' => ): * THUMBNAIL_MARK_TOP_LEFT = 1 * THUMBNAIL_MARK_TOP_RIGHT = 2 * THUMBNAIL_MARK_TOP_CENTER = 3 * THUMBNAIL_MARK_CENTER_CENTER = 4 * THUMBNAIL_MARK_BOTTOM_LEFT = 5 * THUMBNAIL_MARK_BOTTOM_RIGHT = 6 * THUMBNAIL_MARK_BOTTOM_CENTER = 7 * Thumbnail::output($filename, 'data.jpg', $options); * * */ /** * This is a driver for the thumbnail creating * * PHP versions 4 and 5 */ /** * Maximal scaling */ define('THUMBNAIL_METHOD_SCALE_MAX', 0); /** * Minimal scaling */ define('THUMBNAIL_METHOD_SCALE_MIN', 1); /** * Cropping of fragment */ define('THUMBNAIL_METHOD_CROP', 2); /** * Align constants */ define('THUMBNAIL_ALIGN_CENTER', 0); define('THUMBNAIL_ALIGN_LEFT', -1); define('THUMBNAIL_ALIGN_RIGHT', +1); define('THUMBNAIL_ALIGN_TOP', -1); define('THUMBNAIL_ALIGN_BOTTOM', +1); define('THUMBNAIL_MARK_TOP_LEFT', 1); define('THUMBNAIL_MARK_TOP_RIGHT', 2); define('THUMBNAIL_MARK_TOP_CENTER', 3); define('THUMBNAIL_MARK_CENTER_CENTER', 4); define('THUMBNAIL_MARK_BOTTOM_LEFT', 5); define('THUMBNAIL_MARK_BOTTOM_RIGHT', 6); define('THUMBNAIL_MARK_BOTTOM_CENTER', 7); // }}} // {{{ class Thumbnail { // {{{ /** * Create a GD image resource from given input. * * This method tried to detect what the input, if it is a file the * createImageFromFile will be called, otherwise createImageFromString(). * * @param mixed $input The input for creating an image resource. The value * may a string of filename, string of image data or * GD image resource. * * @return resource An GD image resource on success or false * @access public * @static * @see Thumbnail::imageCreateFromFile(), Thumbnail::imageCreateFromString() */ private static function imageCreate($input) { if ( is_file($input) ) { return Thumbnail::imageCreateFromFile($input); } else if ( is_string($input) ) { return Thumbnail::imageCreateFromString($input); } else { return $input; } } // }}} // {{{ /** * Create a GD image resource from file (JPEG, PNG support). * * @param string $filename The image filename. * * @return mixed GD image resource on success, FALSE on failure. * @access public * @static */ private static function imageCreateFromFile($filename) { if ( ! is_file($filename) || ! is_readable($filename) ) { trigger_error('Unable to open file "' . $filename . '"', E_USER_NOTICE); return false; } // determine image format list( , , $type) = getimagesize($filename); switch ($type) { case IMAGETYPE_JPEG: return imagecreatefromjpeg($filename); break; case IMAGETYPE_PNG: return imagecreatefrompng($filename); break; case IMAGETYPE_GIF: return imagecreatefromgif($filename); break; } trigger_error('Unsupport image type', E_USER_NOTICE); return false; } // }}} // {{{ /** * Create a GD image resource from a string data. * * @param string $string The string image data. * * @return mixed GD image resource on success, FALSE on failure. * @access public * @static */ private static function imageCreateFromString($string) { if ( ! is_string($string) || empty($string) ) { trigger_error('Invalid image value in string', E_USER_NOTICE); return false; } return imagecreatefromstring($string); } // }}} // {{{ /** * Display rendered image (send it to browser or to file). * This method is a common implementation to render and output an image. * The method calls the render() method automatically and outputs the * image to the browser or to the file. * * @param mixed $input Destination image, a filename or an image string data or a GD image resource * @param array $options Thumbnail options * @return boolean TRUE on success or FALSE on failure. * @access public */ public static function output($input, $output=null, $options=array()) { // Load source file and render image $renderImage = Thumbnail::render($input, $options); if ( ! $renderImage ) { trigger_error('Error rendering image', E_USER_NOTICE); return false; } // Set output image type // By default PNG image $type = isset($options['type']) ? $options['type'] : IMAGETYPE_JPEG; // Before output to browsers send appropriate headers if ( empty($output) ) { $content_type = image_type_to_mime_type($type); if ( ! headers_sent() ) { header('Content-Type: ' . $content_type); } else { trigger_error('Headers have already been sent. Could not display image.', E_USER_NOTICE); return false; } } // Define outputing function switch ($type) { case IMAGETYPE_PNG: $result = empty($output) ? imagepng($renderImage) : imagepng($renderImage, $output); break; case IMAGETYPE_JPEG: $result = empty($output) ? imagejpeg($renderImage, null, 1) : imagejpeg($renderImage, $output, 100); break; case IMAGETYPE_GIF: $result = empty($output) ? imagegif($renderImage) : imagegif($renderImage, $output); break; default: user_error('Image type ' . $content_type . ' not supported by PHP', E_USER_NOTICE); return false; } // Output image (to browser or to file) if ( ! $result ) { trigger_error('Error output image', E_USER_NOTICE); return false; } // Free a memory from the target image imagedestroy($renderImage); return true; } // }}} // {{{ render() /** * Draw thumbnail result to resource. * * @param mixed $input Destination image, a filename or an image string data or a GD image resource * @param array $options Thumbnail options * * @return boolean TRUE on success or FALSE on failure. * @access public * @see Thumbnail::output() */ private static function render($input, $options=array()) { // Create the source image $sourceImage = Thumbnail::imageCreate($input); if ( ! is_resource($sourceImage) ) { trigger_error('Invalid image resource', E_USER_NOTICE); return false; } $sourceWidth = imagesx($sourceImage); $sourceHeight = imagesy($sourceImage); // Set default options static $defOptions = array( 'width' => 150, 'height' => 150, 'method' => THUMBNAIL_METHOD_SCALE_MAX, 'halign' => THUMBNAIL_ALIGN_CENTER, 'valign' => THUMBNAIL_ALIGN_CENTER, 'coord_x1' => 0, 'coord_y1' => 0, 'coord_x2' => 150, 'coord_y2' => 150, 'corner' => 0, 'corcolor' => 'FFFFFF', 'cortransparent' => 0, 'mark' => 0, 'mark-image' => null ); foreach ($defOptions as $k => $v) { if ( ! isset($options[$k]) ) { $options[$k] = $v; } } // Estimate a rectangular portion of the source image and a size of the target image if ( $options['method'] == THUMBNAIL_METHOD_CROP ) { if ( $options['coord_x2'] AND $options['coord_y2']) { $options['coord_x1'] = (!$options['coord_x1'] OR $options['coord_x1'] >= $options['coord_x2']) ? 0 : $options['coord_x1']; $options['coord_y1'] = (!$options['coord_y1'] OR $options['coord_y1'] >= $options['coord_y2']) ? 0 : $options['coord_y1']; $W = floor($options['coord_x2'] - $options['coord_x1']); $H = floor($options['coord_y2'] - $options['coord_y1']); } $W = ($sourceWidth <= ($options['coord_x1']+$options['coord_x2'])) ? $sourceWidth-$options['coord_x1'] : $W; $H = ($sourceHeight <= ($options['coord_y1']+$options['coord_y2'])) ? $sourceHeight-$options['coord_y1'] : $H; $width = ($W >= $options['width']) ? $options['width'] : $W ; $height = ($H >= $options['height']) ? $options['height'] : $H; $Y = $options['coord_y1']; $X = $options['coord_x1']; } else { $X = 0; $Y = 0; $W = $sourceWidth; $H = $sourceHeight; if ( $options['percent'] ) { $width = floor($options['percent'] * $W); $height = floor($options['percent'] * $H); } else { $width = $options['width']; $height = $options['height']; if ( $options['method'] == THUMBNAIL_METHOD_SCALE_MIN ) { $Ww = $W / $width; $Hh = $H / $height; if ( $Ww > $Hh ) { $W = floor($width * $Hh); $X = Thumbnail::_coord($options['halign'], $sourceWidth, $W); } else { $H = floor($height * $Ww); $Y = Thumbnail::_coord($options['valign'], $sourceHeight, $H); } } else { if ( $H > $W ) { $width = floor($height / $H * $W); } else { $height = floor($width / $W * $H); } } } } // Create the target image if ( function_exists('imagecreatetruecolor') ) { $targetImage = imagecreatetruecolor($width, $height); imageAlphaBlending($targetImage, false); imageSaveAlpha($targetImage, true); $transparency = imagecolorallocatealpha($targetImage, 0, 0, 0, 127); imagefill($targetImage, 0, 0, $transparency); } else { $targetImage = imagecreate($width, $height); } if ( ! is_resource($targetImage) ) { trigger_error('Cannot initialize new GD image stream', E_USER_NOTICE); return false; } // Copy the source image to the target image if ( $options['method'] == THUMBNAIL_METHOD_CROP ) { $result = imagecopy($targetImage, $sourceImage, 0, 0, $X, $Y, $W, $H); } elseif ( function_exists('imagecopyresampled') ) { $result = imagecopyresampled($targetImage, $sourceImage, 0, 0, $X, $Y, $width, $height, $W, $H); } else { $result = imagecopyresized($targetImage, $sourceImage, 0, 0, $X, $Y, $width, $height, $W, $H); } if ( ! $result ) { trigger_error('Cannot resize image', E_USER_NOTICE); return false; } if ($options['corner'] > 0) { /* corner background-color */ $radius = $options['corner']; $colour = $options['corcolor']; $source_width = $width; $source_height = $height; $corner_image = imagecreatetruecolor($radius,$radius); $clear_colour = imagecolorallocate($corner_image,0,0,0); $solid_colour = imagecolorallocate( $corner_image, hexdec( substr( $colour, 0, 2 ) ), hexdec( substr( $colour, 2, 2 ) ), hexdec( substr( $colour, 4, 2 ) ) ); imagecolortransparent($corner_image,$clear_colour); imagefill( $corner_image, 0, 0, $solid_colour ); imagefilledellipse($corner_image, $radius, $radius, $radius * 2, $radius * 2, $clear_colour ); imagecopymerge($targetImage, $corner_image, 0, 0, 0, 0, $radius, $radius, 100 ); $corner_image = imagerotate( $corner_image, 90, 0 ); imagecopymerge($targetImage, $corner_image, 0, $source_height - $radius, 0, 0, $radius, $radius, 100 ); $corner_image = imagerotate( $corner_image, 90, 0 ); imagecopymerge($targetImage, $corner_image, $source_width - $radius, $source_height - $radius, 0, 0, $radius, $radius, 100); $corner_image = imagerotate( $corner_image, 90, 0 ); imagecopymerge($targetImage,$corner_image,$source_width - $radius, 0, 0, 0, $radius, $radius, 100); } if ($options['cortransparent'] > 0) { /* corner (transparent) */ $bwidth = $options['cortransparent']; $width_orig = $width; $height_orig = $height; $img = $targetImage; $mask = imagecreatetruecolor($width_orig, $height_orig); $white = imagecolorallocate($mask, 255, 255, 255); imagefill($mask, 0, 0, $white); $cornerImg = imagecreatetruecolor($bwidth, $bwidth); $transp = imagecolorallocate($cornerImg, 0, 0, 0); imagefill($cornerImg, 0, 0, $transp); $bgc = imagecolorallocate($cornerImg, 255, 255, 255); imagefilledellipse($cornerImg, $bwidth, $bwidth, $bwidth*2, $bwidth*2, $bgc); imagecolortransparent($cornerImg, $bgc); imagecopymerge($mask, $cornerImg, 0, 0, 0, 0, $bwidth, $bwidth, 100); $cornerImg = imagerotate($cornerImg, 270,0); imagecopymerge($mask, $cornerImg, $width_orig-$bwidth, 0, 0, 0, $bwidth, $bwidth, 100); $cornerImg = imagerotate($cornerImg, 270,0); imagecopymerge($mask, $cornerImg, $width_orig-$bwidth, $height_orig-$bwidth, 0, 0, $bwidth, $bwidth, 100); $cornerImg = imagerotate($cornerImg, 270,0); imagecopymerge($mask, $cornerImg, 0, $height_orig-$bwidth, 0, 0, $bwidth, $bwidth, 100); $newImage = imagecreatetruecolor( $width_orig, $height_orig ); imagesavealpha( $newImage, true ); $allocatedAlpha=imagecolorallocatealpha( $newImage, 0, 0, 0, 127 ); imagefill( $newImage, 0, 0, $allocatedAlpha ); for( $x = 0; $x < $width_orig; $x++ ) { for( $y = 0; $y < $height_orig; $y++ ) { $alpha = imagecolorsforindex( $mask, imagecolorat( $mask, $x, $y ) ); $alpha = 127 - floor( $alpha['red'] / 2 ); $colour = imagecolorsforindex( $img, imagecolorat( $img, $x, $y ) ); imagesetpixel( $newImage, $x, $y, imagecolorallocatealpha( $newImage, $colour[ 'red' ], $colour[ 'green' ], $colour[ 'blue' ], $alpha ) ); } } $targetImage = $newImage; } if ($options['mark'] > 0 AND $options['mark-image']) { imagealphablending($targetImage, true); if(!file_exists($options['mark-image'])) die("Cannot watermark image"); $maskwatermark = imagecreatefrompng($options['mark-image']); $owidth = imagesx($maskwatermark); $oheight = imagesy($maskwatermark); $m_width = 0; $m_height = 0; switch ($options['mark']) { case 1: // top left break; case 2: // top right $m_width = ($width-$owidth); break; case 3: // top center $m_width = ($width-$owidth)/2; break; case 4: // center center $m_width = ($width-$owidth)/2; $m_height = ($height-$oheight)/2; break; case 5: // bottom left $m_height = ($height-$oheight); break; case 6: // bottom right $m_width = ($width-$owidth); $m_height = ($height-$oheight); break; case 7: // bottom center $m_width = ($width-$owidth)/2; $m_height = ($height-$oheight); break; default: user_error('Image type ' . $content_type . ' not supported by PHP', E_USER_NOTICE); return false; } imagecopy($targetImage, $maskwatermark, $m_width, $m_height, 0, 0, $owidth, $oheight); } imagedestroy($sourceImage); return $targetImage; } // }}} // {{{ _coord() private static function _coord($align, $param, $src) { if ( $align < THUMBNAIL_ALIGN_CENTER ) { $result = 0; } elseif ( $align > THUMBNAIL_ALIGN_CENTER ) { $result = $param - $src; } else { $result = ($param - $src) >> 1; } return $result; } // }}} }