Home
PHP
Tech Tube
MySQL
Linux
CSS&HTML
JavaScript

PHP image edit class

This class implements image editing options like multiple resize options, crops, watermarks, blurs, color changes, generation of gradients and so on. The class uses GD library.
<?php
/**
 * NOTE: The class requires GD library
 * @package Sami's Image edit class
 * @version $Id: samis_image.class.php v.1.1 2015-07-28 10:03:00 $
 * @author Samuil Banti http://www.samiwell.eu/
 * @copyright (C) 2015 - Samuil Banti
 * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
**/
class samis_image {
    
    /**
     * Check if given file is an alowed image. The allowed formats are jpg, jpeg, png and gif.
     * 
     * WARNING: The function may triget an error if the file do not exist.
     *
     * @param $file_path - The path to the image.
     * @return true on success OR false on falure.
     */
    public function if_alowed_image($file_path) 
    {
        $alowed_types = array('image/pjpeg', 'image/jpeg', 'image/png', 'image/gif');
        $allowed_extentions = array('jpg', 'jpeg', 'png', 'gif');
        
        if(!file_exists($file_path) || !is_file($file_path)) {
            trigger_error('The file "'.$file_path.'" do not exist!', E_USER_NOTICE);
            return false;
        }
        // Check if MIME type is allowed if possible
        if(function_exists('mime_content_type')) {
            $file_type = mime_content_type($file_path);
            $file_type = explode(';', $file_type); // Make sure that the mime_content_type result is plain MIME type
            $file_type = trim($file_type[0]); // --"--
            if(!in_array($file_type, $alowed_types)) {
                return false;
            }
        } 
        // Check if file extention is allowed
        $file_extention = strtolower(pathinfo($file_path, PATHINFO_EXTENSION));
        if(!in_array($file_extention, $allowed_extentions)) {
            return false;
        }
        
        return true;
    }
    
    /**
     * Display image generated by image identifier in the browser.
     * 
     * @param object $im - The image identifier.
     */
    public function display_im($im) 
    {
        header("Content-type: image/png"); 
        imagepng($im); 
        imagedestroy($im); 
        exit;
    }

    /**
     * Gets the RGB representation of HEX color.
     *
     * @param string $hex_color - The color in HEX format.
     * @return array with 3 values of the RGB color.
     */
    public function hex_to_rgb($hex_color) 
    {
        $hex_color = trim($hex_color, ' #');
        $rgb_color = array();
        $rgb_color[] = hexdec(substr($hex_color, 0, 2));
        $rgb_color[] = hexdec(mb_substr($hex_color, 2, 2));
        $rgb_color[] = hexdec(mb_substr($hex_color, 4, 2));
        return $rgb_color;
    }
    
    /**
     * Generates the hex value of a given RGB color including the number sign (#).
     * 
     * @param array $rgb_color - The RGB collor.
     * @return string $hex_color - The HEX collor.
     */
    public function rgb_to_hex($rgb_color) 
    {
        $hex_color = '#';
        $hex_color .= str_pad(dechex($rgb_color[0]), 2, 0, STR_PAD_LEFT);
        $hex_color .= str_pad(dechex($rgb_color[1]), 2, '0', STR_PAD_LEFT);
        $hex_color .= str_pad(dechex($rgb_color[2]), 2, '0', STR_PAD_LEFT);
        return $hex_color;
    }

    /**
     * Get image information - width, height and MIME type.
     *
     * @param $file_path - The path to the image file.
     * @return object with width, height and MIME type on success OR false on falure.
     */
    public function get_img_info($file_path) 
    {
        $if_alowed_image = $this->if_alowed_image($file_path);
        if( empty($if_alowed_image) ) {
            return false;
        }

        $img_size = getimagesize($file_path);

        $img_info = new stdClass;
        $img_info->width    = $img_size[0];
        $img_info->height   = $img_size[1];
        $img_info->mime     = $img_size['mime'];

        return $img_info;
    }
    
    /**
     * Retrns object with image height and width from an image identifier.
     * 
     * @param resource of type (gd) $im - The image identifier.
     * @return object $img_info Object with the image sizes.
     */
    public function get_img_sizes($im)
    {
        $img_info = new stdClass;
        $img_info->width    = imagesx($im);
        $img_info->height   = imagesy($im);
        return $img_info;
    }

    /**
     * Creates image identifier from png, jpg or gif image.
     *
     * @param string $file_path - The path to the image file.
     * @return resource of type (gd) $im - The image identifier OR false on falure.
     */
    public function create_image_from($file_path) 
    {
        $img_info = $this->get_img_info($file_path);
        if(!$img_info) {
            return false;
        }

        switch($img_info->mime) {
            case 'image/png':
                $im = imagecreatefrompng($file_path);
		imageAlphaBlending($im, true);
		imageSaveAlpha($im, true);
                break;
            case 'image/gif':
                $im = imagecreatefromgif($file_path);
                break;
            case 'image/jpeg':
            case 'image/pjpeg':
                $im = imagecreatefromjpeg($file_path);
                break;
            default:
                trigger_error('Invalid MIME type!', E_USER_NOTICE);
                return false;
        }
        return $im;
    }

    /**
     * Saves the given image identifier on a given location.
     *
     * WARNING: The function generates Note on falure!
     *
     * @param resource of type (gd) $im - The image identifier.
     * @param string $save_path - The file path to save to.
     * @param int $quality - The quality of the image.
     * @return false on falure OR true on success.
     */
    public function save_img($im, $save_path, $quality = false) 
    {
        $dir_name = pathinfo($save_path, PATHINFO_DIRNAME);
        if(!is_dir($dir_name)) {
            trigger_error('The directory "'.$dir_name.'" do not exists!', E_USER_NOTICE);
            return false;
        }

        $file_type = strtolower(pathinfo($save_path, PATHINFO_EXTENSION));
        switch($file_type) {
            case 'png':
                $quality = empty($quality) ? 9 : $quality;
                imagepng($im, $save_path, $quality);
                break;
            case 'gif':
                imagegif($im, $save_path);
                break;
            case 'jpeg':
            case 'jpg':
                $quality = empty($quality) ? 100 : $quality;
                imagejpeg($im, $save_path, $quality);
                break;
            default:
                trigger_error('Unknown target file type!', E_USER_NOTICE);
                return false;
        }
        return true;
    }

    /**
     * Resizes image identifier to exact height and width given.
     *
     * @param resource of type (gd) $im - The image identifier.
     * @param int $new_width - The width of the new image.
     * @param int $new_height - The height of the new image.
     * @return resource of type (gd) $new_img - The image identifier for the resized image on sucess OR false on falure.
     */
    public function strict_resize($im, $new_width, $new_height) 
    {
        $new_img = imagecreatetruecolor($new_width, $new_height);
        $img_info = $this->get_img_sizes($im);
        
        //if(DO MIME TYPE CHECK FOR 'image/png') {
            imagealphablending($new_img, false);
            imagesavealpha($new_img, true);
            $transparent = imagecolorallocatealpha($new_img, 255, 255, 255, 127);
            imagefilledrectangle($new_img, 0, 0, $new_width, $new_height, $transparent);
        //}
        imagecopyresampled($new_img, $im, 0, 0, 0, 0, $new_width, $new_height, $img_info->width, $img_info->height);
        return $new_img;
    }

    /**
     * Resizes the given image identifier by given width and proportional height.
     *
     * @param resource of type (gd) $im - The image identifier.
     * @param int $new_width - The new width of the image.
     * @return resource of type (gd) $new_img - The image identifier for the resized image on sucess OR false on falure.
     */
    public function width_resize($im, $new_width) 
    {
        $img_info = $this->get_img_sizes($im);

        $proportion = $new_width / $img_info->width;
        $new_height = $img_info->height * $proportion;

        $new_img = $this->strict_resize($im, $new_width, $new_height);
        return $new_img;
    }

    /**
     * Resizes the given image by given height and proportional width.
     *
     * @param resource of type (gd) $im - The image identifier.
     * @param int $new_height - The height of the new image.
     * @return resource of type (gd) $new_img - The image identifier for the resized image on sucess OR false on falure.
     */
    public function height_resize($im, $new_height) 
    {
        $img_info = $this->get_img_sizes($im);

        $proportion = $new_height / $img_info->height;
        $new_width = $img_info->width * $proportion;

        $new_img = $this->strict_resize($im, $new_width, $new_height);
        return $new_img;
    }

    /**
     * Resizes a given image identifier to fit in a given width and height. The proportions of the image will remain the same.
     *
     * WARNING: the function MAY generate Note on falure!
     *
     * @param resource of type (gd) $im - The image identifier.
     * @param int $new_w - The width of the new image.
     * @param int new_h - The height of the new image.
     * @return resource of type (gd) $new_img - The image identifier for the resized image on sucess OR false on falure.
     */
    public function img_fit_in($im, $new_width, $new_height) 
    {
        $img_info = $this->get_img_sizes($im);

        if($img_info->height <= $new_height && $img_info->width <= $new_width) {
            return $im;
        } else if($img_info->height > $img_info->width) {
            $im = $this->height_resize($im, $new_height);
        } elseif($img_info->width > $img_info->height) {
            $im = $this->width_resize($im, $new_width);
        } else {
            if($new_width < $new_height) {
                $im = $this->width_resize($im, $new_width);
            } elseif($new_width > $new_height) {
                $im = $this->height_resize($im, $new_height);
            } else {
                $im = $this->strict_resize($im, $new_width, $new_height);
            }
        }
        return $im;
    }

    /**
     * Resizes the image to the begest of the given values and fills up to the desired size with a given color or transparancy.
     *
     * @param resource of type (gd) $im - The image identifier.
     * @param int $new_width - The new image width.
     * @param int $new_height - The new image height.
     * @param string $hex_color - The HEX color to use to fill pup the new image size if needed.
     * @param resource of type (gd) $img_fill_up_to  - The image identifier for the resized image.
     */
    public function img_fill_up_to($im, $new_width, $new_height, $hex_color = "FFFF00", $png_opacity = false) 
    {
        $img_info = $this->get_img_sizes($im);

        $rgb_color = $this->hex_to_rgb($hex_color);

        $w_ratio = $new_width / $img_info->width;
        $h_ratio = $new_height / $img_info->height;

        if (($img_info->width <= $new_width) && ($img_info->height <= $new_height)) {
            $w = $img_info->width;
            $h = $img_info->height;
        } elseif (($w_ratio * $new_height) < $new_height) {
            $h = ceil($w_ratio * $new_height);
            $w = $new_height;
        } else {
            $w = ceil($h_ratio * $new_width);
            $h = $new_height;
        }

        $new_img = imagecreatetruecolor(round($w), round($h));

        if($png_opacity == true) {
            imagealphablending($new_img, false);
            imagesavealpha($new_img, true);
            $transparent = imagecolorallocatealpha($new_img, 255, 255, 255, 127);
            imagefilledrectangle($new_img, 0, 0, $new_width, $new_height, $transparent);
        }
        imagecopyresampled($new_img, $im, 0, 0, 0, 0, $w, $h, $img_info->width, $img_info->height);
        $img_fill_up_to = imagecreatetruecolor($new_width, $new_height);
        $backgroundColor = imagecolorallocate($img_fill_up_to, $rgb_color[0], $rgb_color[1], $rgb_color[2]);

        if($png_opacity == true) {
            imagealphablending($img_fill_up_to, false);
            imagesavealpha($img_fill_up_to, true);
            $backgroundColor = imagecolorallocatealpha($img_fill_up_to, 255, 255, 255, 127);
            imagefilledrectangle($img_fill_up_to, 0, 0, $new_width, $new_height, $backgroundColor);
        }
        imagefill($img_fill_up_to, 0, 0, $backgroundColor);
        imagecopy($img_fill_up_to, $new_img, (($new_width - $w)/ 2), (($new_height - $h) / 2), 0, 0, $w, $h);

        return $img_fill_up_to;
    }

    /**
     * Use image as wathermark for another image.
     * 
     * @param resource of type (gd) $im - The image identifier.
     * @param string $watermark_file - The path to the watermark image.
     * @param string $stamp_position - The position of the wathermark (default is 'top_left').
     * @param int $marge_x - The indent from the closest X end of the image.
     * @param int $marge_y - The indent from the closest Y end of the image.
     * @return resource of type (gd) $im - The new image identifier.
     */
    public function image_watermark($im, $watermark_file, $stamp_position = false, $marge_x = 0, $marge_y = 0) 
    {
        $stamp = $this->create_image_from($watermark_file);
        
        $sx = imagesx($stamp);
        $sy = imagesy($stamp);
        $im_w = imagesx($im);
        $im_h = imagesy($im);
        
        switch($stamp_position) {
            case 'top_left':
                // No need to do anything
                break;
            case 'top_middle':
                $marge_x = ($im_w/2) - ($sx/2);
                break;
            case 'top_right':
                $marge_x = $im_w - $sx - $marge_x;
                break;
            case 'middle_left':
                $marge_y = ($im_h/2) - ($sy/2);
                break;
            case 'middle_middle':
                $marge_x = ($im_w/2) - ($sx/2);
                $marge_y = ($im_h/2) - ($sy/2);
                break;
            case 'middle_right':
                $marge_x = $im_w - $sx - $marge_x;
                $marge_y = ($im_h/2) - ($sy/2);
                break;
            case 'bottom_left':
                $marge_y = $im_h - $sy - $marge_y;
                break;
            case 'bottom_middle':
                $marge_y = $im_h - $sy - $marge_y;
                $marge_x = ($im_w/2) - ($sx/2);
                break;
            case 'bottom_right':
                $marge_y = $im_h - $sy - $marge_y;
                $marge_x = $im_w - $sx - $marge_x;
                break;
            default:
                // No need to do anything
        }
         
        imagecopy($im, $stamp, $marge_x, $marge_y, 0, 0, $sx, $sy);
        return $im;
    }
    
    /**
     * Set semi transparent overlay over an image.
     * 
     * NOTE: the transparancy is defined in the range from 0 to 127.
     * 
     * @param resource of type (gd) $im - The image identifier.
     * @param string $hex_color - The color of the overlay in HEX format.
     * @param int $transparancy - The transparancy of the overlay - from 0 t 127.
     * @return resource of type (gd) $im - The image identifier of the new image.
     */
    public function set_overlay($im, $hex_color, $transparancy = 50) 
    {
	// Info
	$rgb_color = $this->hex_to_rgb($hex_color);
	$img_info = $this->get_img_sizes($im);
	// Overlay
	$im_overlay = imagecreatetruecolor($img_info->width, $img_info->height);
	imagesavealpha($im_overlay, true);
	$overlay = imagecolorallocatealpha($im_overlay, $rgb_color[0], $rgb_color[1], $rgb_color[2], $transparancy);
	imagefill($im_overlay, 0, 0, $overlay);
	// Assemble
	imagecopy($im, $im_overlay, 0, 0, 0, 0, $img_info->width, $img_info->height);
	return $im;
    }
    
    /**
     * Create gradient image.
     * 
     * @param int $width - The width of the new image.
     * @param int $height - The height of the new image.
     * @param array $colors - An array with the colors starting from the top left corner.
     * @return resource of type (gd) $im - The image identifier of the new image.
     */
    public function create_gradient_img($width=100, $height=100, $colors=array('#FFFFFF','#FF0000','#00FF00','#0000FF')) 
    {
        $im=imagecreatetruecolor($width,$height);

        for($i=0;$i<=3;$i++) {
            $colors[$i] = $this->hex_to_rgb($colors[$i]);
        }

        $rgb = $colors[0];
        for($x=0;$x<=$width;$x++) {
            for($y=0;$y<=$height;$y++) {
                $col=imagecolorallocate($im,$rgb[0],$rgb[1],$rgb[2]);
                imagesetpixel($im,$x-1,$y-1,$col);
                for($i=0;$i<=2;$i++) {
                    $rgb[$i]=
                    $colors[0][$i]*(($width-$x)*($height-$y)/($width*$height)) +
                    $colors[1][$i]*($x*($height-$y)/($width*$height)) +
                    $colors[2][$i]*(($width-$x)*$y/($width*$height)) +
                    $colors[3][$i]*($x*$y/($width*$height));
                }
            }
        }
        return $im;
    }
    
    /**
     * Crop a part of an image. 
     * 
     * WARNING: The finction MAY trigger an error on falure.
     * NOTE: If the image contains transparancy it will be preserved in the crop.
     *
     * @param resource of type (gd) $im - The image identifier.
     * @param int $crop_width - the width of the crop.
     * @param int $crop_height - the height ot the crop.
     * @param int $crop_left - the distance of the crop from the left side of the source image. Note: if false the function will try to center the crop.
     * @param int $crop_top - the distance of the crop from the top of the source image. Note: if false the function will try to center the crop.
     * @return resource of type (gd) $crop - The image identifier for the resized image on sucess OR false on falure.
     */
    public function crop_image($im, $crop_width, $crop_height, $crop_left = false, $crop_top = false) 
    {
        $img_info = $this->get_img_sizes($im);
        if(!$img_info) {
            return false;
        }

        if($crop_width > $img_info->width || $crop_height > $img_info->height) {
            trigger_error("The size of the crop is bigger than the size of the image to crop from.", E_USER_ERROR);
            return false;
        }

        if( is_numeric($crop_left) || is_numeric($crop_top) ) {
            if( ($crop_width+$crop_left) > $img_info->width || ($crop_height+$crop_top) > $img_info->height) {
                trigger_error("The distance of the crop is too big.", E_USER_ERROR);
                return false;
            }
    	}

        if( !is_numeric($crop_left) ) {
            $crop_left = ($img_info->width - $crop_width) / 2;
            $crop_left = round($crop_left);
        }
        if( !is_numeric($crop_top) ) {
            $crop_top = ($img_info->height - $crop_height) / 2;
            $crop_top = round($crop_top);
        }
        
	$crop = imagecreatetruecolor($crop_width, $crop_height);

        imagealphablending($crop, false);
        imagesavealpha($crop, true);
        $backgroundColor = imagecolorallocatealpha($crop, 255, 255, 255, 127);
        imagefilledrectangle($crop, 0, 0, $crop_width, $crop_height, $backgroundColor);
        imagefill($crop, 0, 0, $backgroundColor);

        imagecopy ($crop, $im, 0, 0, $crop_left, $crop_top, $img_info->width, $img_info->height);
        return $crop;
    }
    
    /**
    * Transform the image to black and white collor.
    * @param resource of type (gd) $im - The image identifier.
    * @return resource of type (gd) $new_img - The image identifier for the resized image on sucess OR false on falure.
    */
    public function black_and_white($im){
	imagefilter($im,IMG_FILTER_GRAYSCALE);
	return $im;
    }

    /**
    * Blurs the image.
    * @param resource of type (gd) $im - The image identifier.
    * @param int $blur - The level of blur 1 to 10.
    * @return resource of type (gd) $im - The image identifier for the resized image on sucess OR false on falure.
    */
    public function blur($im, $blur = 5){
	if($blur > 10 || $blur < 1) {
	    trigger_error('The blur value should be between 1 and 10', E_USER_ERROR);
	    return false;
	}
	$im_sizes = $this->get_img_sizes($im);

	for($i=0; $i<$blur; $i++) {
	    $im = $this->strict_resize($im, round($im_sizes->width/3), round($im_sizes->height/3));
	    imagefilter($im,IMG_FILTER_GAUSSIAN_BLUR);
	    $im = $this->strict_resize($im, round($im_sizes->width), round($im_sizes->height));
	}
	return $im;
    }
    
    /**
    * Generate an image of a given text.
    * @param string $font_file - The path to the TTF font file.
    * @param int $font_size - The font size.
    * @param string $text - The text to be generated.
    * @param string $text_color - The color of the text.
    * @param string $background_color - The color of the background. It should be false to get transparent background.
    * @return resource of type (gd) $im - The image identifier for the resized image on sucess OR false on falure
    */
    public function image_text($font_file, $font_size = 20, $text = 'Example text', $text_color = '#000000', $background_color = false) { 
        if(!file_exists($font_file)) { 
	    trigger_error("The font file $font_file does not exist.", E_USER_ERROR);
            return false; 
        } 
        if($text_color) { 
            $rgb_text_color = $this->hex_to_rgb($text_color); 
        } 
        if($background_color) { 
            $rgb_background_color = $this->hex_to_rgb($background_color); 
        } else { 
            $rgb_background_color = array(255, 255, 255); 
        } 
         
        $strlen = strlen($text); 
        $text_width = 0; 
        $text_height = 0; 
        for ($i = 0; $i < $strlen; $i++) { 
            $dimensions = imagettfbbox($font_size, $angle = 0, $font_file, $text[$i]); 
            $text_width += $dimensions[2] + 3; 
            $text_height = ($text_height > $dimensions[1]) ? $text_height : $dimensions[1]; 
        } 
        
        $im = imagecreatetruecolor($text_width, $font_size + $text_height); 
        $transparent = $background_color ? 0 : 127; 
        imagesavealpha($im, true); 
        imagealphablending($im, false); 
        $background_color = imagecolorallocatealpha($im, $rgb_background_color[0], $rgb_background_color[1], $rgb_background_color[2], $transparent); 
        imagefill($im, 0, 0, $background_color); 
         
        $text_color = imagecolorallocate($im, $rgb_text_color[0], $rgb_text_color[1], $rgb_text_color[2]); 
        imagettftext($im, $font_size, 0, 0, $font_size, $text_color, $font_file, $text); 
        return $im;
    }
    
}
Download...