Created
February 16, 2013 02:21
-
-
Save awtprod/4965189 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Place watermark on image | |
* | |
* Options: | |
* - 'input' Input file (path or gd resource) | |
* - 'output' Output path. If not specified, gd resource is returned | |
* - 'watermark' Watermark file (path or gd resource) | |
* - 'quality' Output image quality (JPG only). Value from 0 to 100 | |
* - 'compression' Output image compression (PNG only). Value from 0 to 9 | |
* - 'chmod' What permissions should be applied to destination image | |
* - 'scale' If true, watermark will be scaled fullsize ('position' and 'repeat' won't be taken into account) | |
* - 'strech' If true and scale also set to true, strech watermark to cover whole image | |
* - 'repeat' Should watermark be repeated? This is ignored if 'scale' is set to true or 'position' is custom (array) | |
* - 'position' Watermark position. Possible values: 'top-left', 'top-right', 'bottom-right', 'bottom-left', 'center' or array(x, y) | |
* - 'opacity' Watermark image's opacity (0-100). Default = 100 | |
* - 'afterCallbacks' Functions to be executed after this one | |
* | |
* @param array $options An array of options. | |
* @return mixed boolean or GD resource if output was set to null | |
*/ | |
function watermark(Model $model, $srcFile, $path, $options = array()) { | |
$srcFile = $path . $model->data[$model->alias][$field]; | |
$options = array_merge(array( | |
'afterCallbacks' => null, | |
'scale' => false, | |
'strech' => false, | |
'repeat' => false, | |
'watermark' => 'watermark.png', | |
'output' => '{ROOT}webroot{DS}files{DS}{model}{DS}{field}{DS}', | |
'input' => $srcFile, | |
'position' => 'center', | |
'compression' => 9, | |
'quality' => 100, | |
'chmod' => null, | |
'opacity' => 100 | |
), $options); | |
// if output path (directories) doesn't exist, try to make whole path | |
if (!$this->createPath($options['output'])) { | |
return false; | |
} | |
$img = $this->openImage($options['input']); | |
unset($options['input']); | |
if (empty($img)) { | |
return false; | |
} | |
$src_wm = $this->openImage($options['watermark']); | |
unset($options['watermark']); | |
if (empty($src_wm)) { | |
return false; | |
} | |
// image size | |
$img_im_w = imagesx($img); | |
$img_im_h = imagesy($img); | |
// watermark size | |
$img_wm_w = imagesx($src_wm); | |
$img_wm_h = imagesy($src_wm); | |
if ($options['scale']) { | |
if ($options['strech']) { | |
$r = imagecopyresampled($img, $src_wm, 0, 0, 0, 0, $img_im_w, $img_im_h, $img_wm_w, $img_wm_h); | |
} else { | |
$x = 0; | |
$y = 0; | |
$w = $img_im_w; | |
$h = $img_im_h; | |
if (($img_im_w / $img_im_h) > ($img_wm_w / $img_wm_h)) { | |
$ratio = $img_im_h / $img_wm_h; | |
$w = $ratio * $img_wm_w; | |
$x = round(($img_im_w - $w) / 2); | |
} else { | |
$ratio = $img_im_w / $img_wm_w; | |
$h = $ratio * $img_wm_h; | |
$y = round(($img_im_h - $h) / 2); | |
} | |
$r = imagecopyresampled($img, $src_wm, $x, $y, 0, 0, $w, $h, $img_wm_w, $img_wm_h); | |
} | |
} else if ($options['repeat']) { | |
if (is_array($options['position'])) { | |
$options['position'] = 5; | |
} | |
switch ($options['position']) { | |
case 'top-left': | |
for ($y=0; $y<$img_im_h; $y+=$img_wm_h) { | |
for ($x=0; $x<$img_im_w; $x+=$img_wm_w) { | |
$r = $this->imagecopymerge_alpha($img, $src_wm, $x, $y, 0, 0, $img_wm_w, $img_wm_h, $options['opacity']); | |
} | |
} | |
break; | |
case 'top-right': | |
for ($y=0; $y<$img_im_h; $y+=$img_wm_h) { | |
for ($x=$img_im_w; $x>-$img_wm_w; $x-=$img_wm_w) { | |
$r = $this->imagecopymerge_alpha($img, $src_wm, $x, $y, 0, 0, $img_wm_w, $img_wm_h, $options['opacity']); | |
} | |
} | |
break; | |
case 'bottom-right': | |
for ($y=$img_im_h; $y>-$img_wm_h; $y-=$img_wm_h) { | |
for ($x=$img_im_w; $x>-$img_wm_w; $x-=$img_wm_w) { | |
$r = $this->imagecopymerge_alpha($img, $src_wm, $x, $y, 0, 0, $img_wm_w, $img_wm_h, $options['opacity']); | |
} | |
} | |
break; | |
case 'bottom-left': | |
for ($y=$img_im_h; $y>-$img_wm_h; $y-=$img_wm_h) { | |
for ($x=0; $x<$img_im_w; $x+=$img_wm_w) { | |
$r = $this->imagecopymerge_alpha($img, $src_wm, $x, $y, 0, 0, $img_wm_w, $img_wm_h, $options['opacity']); | |
} | |
} | |
break; | |
case 'center': | |
default: | |
$pos_x = -(($img_im_w%$img_wm_w)/2); | |
$pos_y = -(($img_im_h%$img_wm_h)/2); | |
for ($y=$pos_y; $y<$img_im_h; $y+=$img_wm_h) { | |
for ($x=$pos_x; $x<$img_im_w; $x+=$img_wm_w) { | |
$r = $this->imagecopymerge_alpha($img, $src_wm, $x, $y, 0, 0, $img_wm_w, $img_wm_h, $options['opacity']); | |
} | |
} | |
break; | |
} | |
} else { | |
// custom location | |
if (is_array($options['position'])) { | |
list($pos_x, $pos_y) = $options['position']; | |
} else { | |
// predefined location | |
switch ($options['position']) { | |
case 'top-left': | |
$pos_x = 0; | |
$pos_y = 0; | |
break; | |
case 'top-right': | |
$pos_x = $img_im_w - $img_wm_w; | |
$pos_y = 0; | |
break; | |
case 'bottom-right': | |
$pos_x = $img_im_w - $img_wm_w; | |
$pos_y = $img_im_h - $img_wm_h; | |
break; | |
case 'bottom-left': | |
$pos_x = 0; | |
$pos_y = $img_im_h - $img_wm_h; | |
break; | |
case 'center': | |
default: | |
$pos_x = round(($img_im_w - $img_wm_w) / 2); | |
$pos_y = round(($img_im_h - $img_wm_h) / 2); | |
break; | |
} | |
} | |
$r = $this->imagecopymerge_alpha($img, $src_wm, $pos_x, $pos_y, 0, 0, $img_wm_w, $img_wm_h, $options['opacity']); | |
} | |
if (!$r) { | |
return false; | |
} | |
if (!$this->afterCallbacks($img, $options['afterCallbacks'])) { | |
return false; | |
} | |
return $this->saveImage($img, $options); | |
} | |
/** | |
* Get file extension | |
* | |
* @param string $filename Filename | |
* @return string | |
*/ | |
function getExtension($filename) { | |
if (!is_string($filename)) { | |
return ''; | |
} | |
$pos = strrpos($filename, '.'); | |
if ($pos === false) { | |
return ''; | |
} | |
return strtolower(substr($filename, $pos + 1)); | |
} | |
/** | |
* Open image as gd resource | |
* | |
* @param string $input Input (path) image | |
* @return mixed | |
*/ | |
function openImage($input) { | |
if (is_resource($input)) { | |
if (get_resource_type($input) == 'gd') { | |
return $input; | |
} | |
} else { | |
switch ($this->getImageType($input)) { | |
case 'jpg': | |
return imagecreatefromjpeg($input); | |
break; | |
case 'png': | |
return imagecreatefrompng($input); | |
break; | |
case 'gif': | |
return imagecreatefromgif($input); | |
break; | |
} | |
} | |
return false; | |
} | |
/** | |
* Get image type from file | |
* | |
* @param string $input Input (path) image | |
* @param string $extension (optional) Extension (type) | |
* @param boolean $extension If true, check by extension | |
* @return string | |
*/ | |
function getImageType($input, $extension = false) { | |
if ($extension) { | |
switch ($this->getExtension($input)) { | |
case 'jpg': | |
return 'jpg'; | |
break; | |
case 'png': | |
return 'png'; | |
break; | |
case 'gif': | |
return 'gif'; | |
break; | |
} | |
} else if (is_string($input) && is_file($input)) { | |
$info = getimagesize($input); | |
switch ($info['mime']) { | |
case 'image/pjpeg': | |
case 'image/jpeg': | |
case 'image/jpg': | |
return 'jpg'; | |
break; | |
case 'image/x-png': | |
case 'image/png': | |
return 'png'; | |
break; | |
case 'image/gif': | |
return 'gif'; | |
break; | |
} | |
} | |
return ''; | |
} | |
/** | |
* Save image gd resource as image | |
* | |
* Image type is determined by $output extension so it must be present. | |
* | |
* Options: | |
* - 'compression' Output image's compression. Currently only PNG (value 0-9) supports this | |
* - 'quality' Output image's quality. Currently only JPG (value 0-100) supports this | |
* - 'output' Output path. If not specified, image resource is returned | |
* | |
* @param mixed $im Image resource | |
* @param string $output Output path | |
* @param mixed $options An array of additional options | |
* @return boolean | |
*/ | |
function saveImage(&$im, $options = array()) { | |
foreach (array('compression', 'quality', 'chmod') as $v) { | |
if (is_null($options[$v])) { | |
unset($options[$v]); | |
} | |
} | |
$options = array_merge(array( | |
'compression' => 9, | |
'quality' => 100, | |
'output' => null | |
), $options); | |
switch ($this->getImageType($options['output'], true)) { | |
case 'jpg': | |
if (ImageJPEG($im, $options['output'], $options['quality'])) { | |
if (!empty($options['chmod'])) { | |
chmod($options['output'], $options['chmod']); | |
} | |
return true; | |
} | |
break; | |
case 'png': | |
if (ImagePNG($im, $options['output'], $options['compression'])) { | |
if (!empty($options['chmod'])) { | |
chmod($options['output'], $options['chmod']); | |
} | |
return true; | |
} | |
break; | |
case 'gif': | |
if (ImageGIF($im, $options['output'])) { | |
if (!empty($options['chmod'])) { | |
chmod($options['output'], $options['chmod']); | |
} | |
return true; | |
} | |
break; | |
case '': | |
return $im; | |
break; | |
} | |
unset($im); | |
return false; | |
} | |
/** | |
* Try to create specified path | |
* | |
* If specified path is empty, return true | |
* | |
* @param string $output_path | |
* @param mixed $chmod Each folder's permissions | |
* @return boolean | |
*/ | |
function createPath($output_path, $chmod = 0777) { | |
if (empty($output_path)) { | |
return true; | |
} | |
$arr_output_path = explode(DIRECTORY_SEPARATOR, $output_path); | |
unset($arr_output_path[count($arr_output_path)-1]); | |
$dir_path = implode($arr_output_path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR; | |
if (!file_exists($dir_path)) { | |
if (!mkdir($dir_path, $chmod, true)) { | |
return false; | |
} | |
} | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment