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...