mirror of
https://github.com/Oreolek/ifhub.club.git
synced 2024-07-01 05:55:02 +03:00
Разработана библиотека для оперирования с изображениями LiveImage. Пример базовой функциональности внедрен на базе функции func_img_resize().
This commit is contained in:
parent
a9bcec1f01
commit
438b544718
|
@ -196,6 +196,7 @@ function func_header_location($sLocation) {
|
|||
* @return unknown
|
||||
*/
|
||||
function func_img_resize($sFileSrc,$sDirDest,$sFileDest,$iWidthMax,$iHeightMax,$iWidthDest=null,$iHeightDest=null,$bForcedMinSize=true) {
|
||||
/**
|
||||
if (!($aSize=getimagesize($sFileSrc))) {
|
||||
return false;
|
||||
}
|
||||
|
@ -275,6 +276,39 @@ function func_img_resize($sFileSrc,$sDirDest,$sFileDest,$iWidthMax,$iHeightMax,$
|
|||
}
|
||||
}
|
||||
return false;
|
||||
**/
|
||||
require_once Config::Get('path.root.engine').'/lib/external/LiveImage/Image.php';
|
||||
$oImage=new LiveImage($sFileSrc);
|
||||
|
||||
if($oImage->get_last_error()){
|
||||
return false;
|
||||
}
|
||||
$sFileDest.='.'.$oImage->get_image_params('format');
|
||||
if (($oImage->get_image_params('width')>$iWidthMax)
|
||||
or ($oImage->get_image_params('height')>$iHeightMax)) {
|
||||
return false;
|
||||
}
|
||||
$sFileFullPath=Config::Get('path.root.server').'/'.$sDirDest.'/'.$sFileDest;
|
||||
@func_mkdir(Config::Get('path.root.server'),$sDirDest);
|
||||
|
||||
if ($iWidthDest) {
|
||||
if (!$bForcedMinSize and ($iWidthDest>$oImage->get_image_params('width'))) {
|
||||
$iWidthDest=$oImage->get_image_params('width');
|
||||
}
|
||||
/**
|
||||
* Ресайзим и выводим результат в файл.
|
||||
* Если не задана новая высота, то применяем масштабирование.
|
||||
*/
|
||||
$oImage->resize($iWidthDest,$iHeightDest,(!$iHeightDest));
|
||||
$oImage->output(null,$sFileFullPath);
|
||||
chmod($sFileFullPath,0666);
|
||||
return $sFileDest;
|
||||
} elseif (copy($sFileSrc,$sFileFullPath)) {
|
||||
chmod($sFileFullPath,0666);
|
||||
return $sFileDest;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
550
engine/lib/external/LiveImage/Image.php
vendored
Normal file
550
engine/lib/external/LiveImage/Image.php
vendored
Normal file
|
@ -0,0 +1,550 @@
|
|||
<?php
|
||||
/**
|
||||
* LiveImage, library for workin with images.
|
||||
* (c) Alex Kachayev, http://www.kachayev.ru
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
* See http://www.gnu.org/copyleft/lesser.html
|
||||
*
|
||||
* LiveImage:
|
||||
* Main functions for resize, crop and stylize your picture.
|
||||
*
|
||||
* @author Alex Kachayev
|
||||
* @version 1.2
|
||||
* @package LiveImage
|
||||
*/
|
||||
|
||||
class LiveImage {
|
||||
/**
|
||||
* Image object handler
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $image=null;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $truecolor=true;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $width=0;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $height=0;
|
||||
/**
|
||||
* Color param (RGB code)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $color=array('r'=>255,'g'=>255,'b'=>255);
|
||||
/**
|
||||
* Pixel font size
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $font_size=20;
|
||||
/**
|
||||
* Font name for making image labels.
|
||||
* For saving true type fonts use /font directory.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $font='';
|
||||
/**
|
||||
* Resizing scale
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $scale = 1;
|
||||
/**
|
||||
* Format of image file\object
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $format='';
|
||||
/**
|
||||
* Error texts
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $error_messages = array(
|
||||
1 => 'Can`t create image',
|
||||
2 => 'No font was given',
|
||||
3 => 'No file was given',
|
||||
4 => 'Can`t open image from file',
|
||||
5 => 'Unknown file format given'
|
||||
);
|
||||
/**
|
||||
* Last error text
|
||||
*
|
||||
* @var strng
|
||||
*/
|
||||
protected $last_err_text='';
|
||||
/**
|
||||
* Last error code
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $last_err_num=0;
|
||||
|
||||
/**
|
||||
* Создает объект изображения из переданного файла
|
||||
*
|
||||
* @param string $file
|
||||
* @return bool
|
||||
*/
|
||||
public function __construct($file) {
|
||||
if(!$file || !($size=getimagesize($file))) {
|
||||
$this->set_last_error(3);
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Определяем тип файла изображения
|
||||
*/
|
||||
switch ($size['mime']) {
|
||||
case 'image/png':
|
||||
$tmp=imagecreatefrompng($file);
|
||||
$this->format='png';
|
||||
break;
|
||||
case 'image/gif':
|
||||
$tmp=imagecreatefromgif($file);
|
||||
$this->format='gif';
|
||||
break;
|
||||
case 'image/jpeg':
|
||||
$tmp=imagecreatefromjpeg($file);
|
||||
$this->format='jpg';
|
||||
break;
|
||||
default:
|
||||
$this->set_last_error(5);
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Если изображение не удалось создать
|
||||
*/
|
||||
if(!$tmp){
|
||||
$this->set_last_error(4);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->image=$tmp;
|
||||
$this->width=$size[0];
|
||||
$this->height=$size[1];
|
||||
$this->truecolor=true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize handle image
|
||||
*
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
* @param int $src_resize
|
||||
* @param int $scale
|
||||
* @return mixed
|
||||
*/
|
||||
public function resize($width=null,$height=null,$scale=false) {
|
||||
$this->clear_error();
|
||||
/**
|
||||
* Если не указана новая высота, значит применяем масштабирование.
|
||||
* Если не указана ширина, то "забираем" ширину исходного.
|
||||
*/
|
||||
$height=(!$height)?1:$height;
|
||||
$width=(!$width)?$this->width:$width;
|
||||
|
||||
if( $scale ){
|
||||
$scale_x = $this->width / $width;
|
||||
$scale_y = $this->height / $height;
|
||||
$this->scale = min($scale_x, $scale_y);
|
||||
|
||||
$width = round($this->width / $this->scale);
|
||||
$height = round($this->height / $this->scale);
|
||||
}
|
||||
|
||||
if($this->truecolor) {
|
||||
$tmp=imagecreatetruecolor($width,$height);
|
||||
} else {
|
||||
$tmp=imagecreate($width,$height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Если темп-изображение не создано, ставим отметку об ошикбе
|
||||
*/
|
||||
if(!$tmp) {
|
||||
$this->set_last_error(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
@imagesavealpha($tmp,true);
|
||||
@imagealphablending($tmp,false);
|
||||
|
||||
if(!@imagecopyresampled($tmp,$this->image,0,0,0,0,$width,$height,$this->width,$this->height)) {
|
||||
imagedestroy($tmp);
|
||||
return false;
|
||||
}
|
||||
|
||||
imagedestroy($this->image);
|
||||
$this->image=$tmp;
|
||||
$this->width=$width;
|
||||
$this->height=$height;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return image object
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_image() {
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return image params
|
||||
*
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
public function get_image_params($key=null) {
|
||||
$params=array(
|
||||
'width' => $this->width,
|
||||
'height' => $this->height,
|
||||
'truecolor' => $this->truecolor,
|
||||
'format' => $this->format
|
||||
);
|
||||
if(is_null($key)) {
|
||||
return $params;
|
||||
}
|
||||
|
||||
if(array_key_exists($key,$params)){
|
||||
return $params[$key];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for font params
|
||||
*
|
||||
* @param string $font_size
|
||||
* @param int $font_angle
|
||||
* @param string $name
|
||||
*/
|
||||
public function set_font($font_size=20,$font_angle=0,$name='') {
|
||||
if($name) {
|
||||
$this->font=$name;
|
||||
}
|
||||
|
||||
$this->font_size=$font_size;
|
||||
$this->font_angle=$font_angle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for color
|
||||
*
|
||||
* @param int $r
|
||||
* @param int $g
|
||||
* @param int $b
|
||||
* @param bool $transparency
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function set_color($r=255,$g=255,$b=255,$transparency=false) {
|
||||
$this->color=array('r'=>$r,'g'=>$g,'b'=>$b);
|
||||
|
||||
if(!$transparency) {
|
||||
$this->color['locate']=imagecolorallocate($this->image,$this->color['r'],$this->color['g'],$this->color['b']);
|
||||
} else {
|
||||
$this->color['locate']=imagecolorallocatealpha($this->image,$this->color['r'],$this->color['g'],$this->color['b'],$transparency);
|
||||
}
|
||||
|
||||
return $this->color['locate'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Make true type font text label on image
|
||||
*
|
||||
* @param string $text
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
* @param bool $unicode
|
||||
* @param int $letter_space
|
||||
* @return bool
|
||||
*/
|
||||
public function ttf_text($text,$x=0,$y=0,$unicode=false,$letter_space=20) {
|
||||
$this->clear_error();
|
||||
|
||||
if(!$this->font) {
|
||||
$this->set_last_error(2);
|
||||
return false;
|
||||
}
|
||||
|
||||
if($unicode) {
|
||||
$text=$this->to_unicode($text);
|
||||
}
|
||||
return imagettftext($this->image,$this->font_size,$this->font_angle,$x,$y,$this->color,$this->font,$text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create text watermark
|
||||
*
|
||||
* @param string $text
|
||||
* @param array $position
|
||||
* @param array $font_color
|
||||
* @param array $bg_color
|
||||
* @param int $font_alpha
|
||||
* @param int $bg_alfa
|
||||
* @return bool
|
||||
*/
|
||||
public function watermark($text, $position=array(0,24), $font_color=array(255, 255, 255), $bg_color=array(0,0,0), $font_alpha=0, $bg_alfa=40 ){
|
||||
$text = " ".$text." ";
|
||||
list($r_font, $g_font, $b_font) = $font_color;
|
||||
list($r_bg, $g_bg, $b_bg) = $bg_color;
|
||||
list($x, $y) = $position;
|
||||
|
||||
/// Вычисляем размер надписи
|
||||
/// Наносим фон надписи согласно расчетам размера и позиции
|
||||
$box = imagettfbbox($this->font_size, 0, $this->font, $text);
|
||||
/// Производим замену отрицательных кодов в позиции
|
||||
/// и кодов вида 1/2 - центрирование относительно оси
|
||||
if(substr_count($x, '-')==1) {
|
||||
$x = $this->width-abs($box[4])-10-substr_replace($x, '', 0, 1);
|
||||
} elseif($x=='1/2') {
|
||||
$x=round(($this->width-abs($box[4]))/2)-5;
|
||||
}
|
||||
if(substr_count($y, '-')==1) {
|
||||
$y = $this->height-abs($box[5])-10-substr_replace($y, '', 0, 1);
|
||||
} elseif($y=='1/2') {
|
||||
$y=round(($this->height-abs($box[5]))/2)-5;
|
||||
}
|
||||
/// Наносим фон для будущей надписи
|
||||
$this->set_color($r_bg, $g_bg, $b_bg, $bg_alfa);
|
||||
imagefilledrectangle($this->image,$x,$y,$x+abs($box[4])+10,$y+abs($box[5])+10,$this->color);
|
||||
|
||||
/// Наносим надпись водянного знака
|
||||
$this->set_color($r_font, $g_font, $b_font, $font_alpha);
|
||||
imagettftext($this->image, $this->font_size, 0, $x+5, $y+abs($box[5])+5, $this->color, $this->font, $text);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make rounded corners
|
||||
*
|
||||
* @param int $radius
|
||||
* @param int $rate
|
||||
* @return bool
|
||||
*/
|
||||
public function round_corners($radius=5, $rate=5) {
|
||||
imagealphablending($this->image, false);
|
||||
imagesavealpha($this->image, true);
|
||||
|
||||
$rs_radius = $radius * $rate;
|
||||
$rs_size = $rs_radius * 2;
|
||||
|
||||
$corner = imagecreatetruecolor($rs_size, $rs_size);
|
||||
imagealphablending($corner, false);
|
||||
|
||||
$trans = imagecolorallocatealpha($corner, 255, 255, 255, 0);
|
||||
imagefill($corner, 0, 0, $trans);
|
||||
|
||||
$positions = array(
|
||||
array(0, 0, 0, 0),
|
||||
array($rs_radius, 0, $this->width - $radius, 0),
|
||||
array($rs_radius, $rs_radius, $this->width - $radius, $this->height - $radius),
|
||||
array(0, $rs_radius, 0, $this->height - $radius),
|
||||
);
|
||||
|
||||
foreach ($positions as $pos) {
|
||||
imagecopyresampled($corner, $this->image, $pos[0], $pos[1], $pos[2], $pos[3], $rs_radius, $rs_radius, $radius, $radius);
|
||||
}
|
||||
|
||||
$lx = $ly = 0;
|
||||
$i = -$rs_radius;
|
||||
$y2 = -$i;
|
||||
$r_2 = $rs_radius * $rs_radius;
|
||||
|
||||
for (; $i <= $y2; $i++) {
|
||||
$y = $i;
|
||||
$x = sqrt($r_2 - $y * $y);
|
||||
|
||||
$y += $rs_radius;
|
||||
$x += $rs_radius;
|
||||
|
||||
imageline($corner, $x, $y, $rs_size, $y, $trans);
|
||||
imageline($corner, 0, $y, $rs_size - $x, $y, $trans);
|
||||
|
||||
$lx = $x;
|
||||
$ly = $y;
|
||||
}
|
||||
|
||||
foreach ($positions as $i => $pos) {
|
||||
imagecopyresampled($this->image, $corner, $pos[2], $pos[3], $pos[0], $pos[1], $radius, $radius, $rs_radius, $rs_radius);
|
||||
}
|
||||
imagedestroy($corner);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make image output in file or in browser.
|
||||
* Can output image in one of this formats: png, gif, jpg.
|
||||
* If you don`t give format, it will use
|
||||
* the format of image object.
|
||||
*
|
||||
* @param string $format
|
||||
* @param string $file
|
||||
*/
|
||||
public function output($format=null,$file=null) {
|
||||
/**
|
||||
* Если формат не указан, значит сохраняем формат исходного объекта
|
||||
*/
|
||||
if(is_null($format)) {
|
||||
$format=$this->format;
|
||||
}
|
||||
/**
|
||||
* Производим преобразование и отдаем результат
|
||||
*/
|
||||
switch($format) {
|
||||
default:
|
||||
case 'png':
|
||||
if(!$file) {
|
||||
header("Content-type: image/png");
|
||||
imagepng($this->image);
|
||||
} else {
|
||||
imagepng($this->image,$file);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'jpg':
|
||||
if(!$file) {
|
||||
header("Content-type: image/jpeg");
|
||||
imagejpeg($this->image);
|
||||
} else {
|
||||
imagejpeg($this->image,$file);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'gif':
|
||||
if(!$file) {
|
||||
header("Content-type: image/gif");
|
||||
imagegif($this->image);
|
||||
} else {
|
||||
imagegif($this->image,$file);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function paste_image($file,$type=0,$copyresized=false,$position=array(0,0),$src_x=0,$src_y=0,$src_w=-1,$src_h=-1,$dst_w=-1,$dst_h=-1) {
|
||||
$this->clear_error();
|
||||
|
||||
if(!$file) {
|
||||
$this->set_last_error(3);
|
||||
return false;
|
||||
}
|
||||
switch($type) {
|
||||
default:
|
||||
case 0:
|
||||
$tmp=imagecreatefrompng($file);
|
||||
break;
|
||||
case 1:
|
||||
$tmp=imagecreatefromjpeg($file);
|
||||
break;
|
||||
case 2:
|
||||
$tmp=imagecreatefromgif($file);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!$tmp) {
|
||||
$this->set_last_error(4);
|
||||
return false;
|
||||
}
|
||||
|
||||
if($copyresized) {
|
||||
$dst_w = round(imagesx($tmp)/$this->scale);
|
||||
$dst_h = round(imagesy($tmp)/$this->scale);
|
||||
} else {
|
||||
$dst_w=$dst_w<0 ? $this->width : $dst_w;
|
||||
$dst_h=$dst_h<0 ? $this->height : $dst_h;
|
||||
}
|
||||
$src_w=$src_w<0 ? imagesx($tmp) : $src_w;
|
||||
$src_h=$src_h<0 ? imagesy($tmp) : $src_h;
|
||||
|
||||
list($dst_x, $dst_y) = $position;
|
||||
|
||||
/// Производим замену отрицательных кодов в позиции
|
||||
/// и кодов вида 1/2 - центрирование относительно оси
|
||||
if(substr_count($dst_x, '-')==1) {
|
||||
$dst_x = $this->width-$dst_w-substr_replace($dst_x, '', 0, 1);
|
||||
} elseif($dst_x=='1/2') {
|
||||
$dst_x=round(($this->width-$dst_w)/2);
|
||||
}
|
||||
if(substr_count($dst_y, '-')==1) {
|
||||
$dst_y = $this->height-$dst_h-substr_replace($dst_y, '', 0, 1);
|
||||
} elseif($dst_y=='1/2') {
|
||||
$dst_y=round(($this->height-$dst_h)/2);
|
||||
}
|
||||
|
||||
if($copyresized) {
|
||||
$ret=imagecopyresized($this->image,$tmp,$dst_x,$dst_y,$src_x,$src_y,$dst_w,$dst_h,$src_w,$src_h);
|
||||
} else {
|
||||
$ret=imagecopy($this->image,$tmp,$dst_x,$dst_y,$src_x,$src_y,$src_w,$src_h);
|
||||
}
|
||||
imagedestroy($tmp);
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
public function rgb($r=255,$g=255,$b=255) {
|
||||
return imagecolorallocate($this->image,$r,$g,$b);
|
||||
}
|
||||
|
||||
public function set_last_error($id) {
|
||||
$this->last_err_text=$this->error_messages[$id];
|
||||
$this->last_err_num=$this->$id;
|
||||
}
|
||||
|
||||
public function get_last_error() {
|
||||
return empty($this->last_err_num) ? false : $this->last_err_text;
|
||||
}
|
||||
|
||||
public function clear_error() {
|
||||
$this->last_err_text='';
|
||||
$this->last_err_num=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string to unicode for making text label using true type font.
|
||||
*
|
||||
* @param string $text
|
||||
* @param string $from
|
||||
* @return string
|
||||
*/
|
||||
protected function to_unicode($text,$from='w') {
|
||||
$text=convert_cyr_string($text,$from,'i');
|
||||
$uni='';
|
||||
|
||||
for($i=0, $len=strlen($text); $i<$len; $i++)
|
||||
{
|
||||
$char=$text{$i};
|
||||
$code=ord($char);
|
||||
$uni.=($code>175) ? "&#".(1040+($code-176)).";" : $char;
|
||||
}
|
||||
|
||||
return $uni;
|
||||
}
|
||||
|
||||
public function destroy_all() {
|
||||
if(imagedestroy($this->image))
|
||||
$this->image=null;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
?>
|
516
engine/lib/external/LiveImage/Watermark.php
vendored
Normal file
516
engine/lib/external/LiveImage/Watermark.php
vendored
Normal file
|
@ -0,0 +1,516 @@
|
|||
<?php
|
||||
/**
|
||||
* LiveImage, library for workin with images.
|
||||
* (c) Alex Kachayev, http://www.kachayev.ru
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
* See http://www.gnu.org/copyleft/lesser.html
|
||||
*
|
||||
* LiveWatermark:
|
||||
* Functions for adding text or image watermark on choosen backend.
|
||||
*
|
||||
* @version 1.2
|
||||
* @package LiveImage
|
||||
*/
|
||||
|
||||
class LiveWatermark {
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $image;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $type;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $width;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $height;
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $marked_image;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $sizes;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $position = "C";
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $offset_x;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $offset_y;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $orientation;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $imageCreated = false;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $gd_version;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fixedColor = '';
|
||||
|
||||
/**
|
||||
* You need to specify either a filename or an image resource
|
||||
* when instatiating object
|
||||
*
|
||||
* @param mixed
|
||||
*/
|
||||
public function __construct($res) {
|
||||
list($this->type, $this->image) = $this->_getImage($res);
|
||||
|
||||
if (!$this->image) {
|
||||
$this->_die_error("Your current PHP setup does not support ". $this->type ." images");
|
||||
}
|
||||
|
||||
$this->width = imagesx($this->image);
|
||||
$this->height = imagesy($this->image);
|
||||
|
||||
$gdinfo = gd_info();
|
||||
if (preg_match('/(\d)\.\d/', $gdinfo["GD Version"], $gdinfo)) {
|
||||
$this->gd_version = $gdinfo[1];
|
||||
} else {
|
||||
$this->gd_version = 0;
|
||||
}
|
||||
unset($gdinfo);
|
||||
}
|
||||
|
||||
public function setType($type) {
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a watermark to the image
|
||||
* Type defaults to TEXT for backwards compatibility
|
||||
*
|
||||
* @param mixed $mark
|
||||
* @param string $type
|
||||
*/
|
||||
public function addWatermark($mark, $type = "TEXT") {
|
||||
if ($type == "TEXT") { // We are going to embed text into the image
|
||||
$this->orientation = ($this->width > $this->height) ? "H" : "V"; // Choose orientation
|
||||
|
||||
$this->sizes = $this->_getTextSizes($mark);
|
||||
|
||||
$this->_getOffsets();
|
||||
|
||||
// Copy a chunk of the original image (this is where the watermark will be placed)
|
||||
$chunk = $this->_getChunk();
|
||||
if (!$chunk) $this->_die_error("Could not extract chunk from image");
|
||||
|
||||
$img_mark = $this->_createEmptyWatermark();
|
||||
$img_mark = $this->_addTextWatermark($mark, $img_mark, $chunk);
|
||||
|
||||
// Delete chunk
|
||||
imagedestroy($chunk);
|
||||
|
||||
// Finish image
|
||||
$this->_createMarkedImage($img_mark, $type, 30);
|
||||
} elseif ($type == "IMAGE") { // We are going to embed an image
|
||||
list($dummy, $mark) = $this->_getImage($mark);
|
||||
$this->sizes = $this->_getImageSizes($mark);
|
||||
|
||||
$this->_getOffsets();
|
||||
|
||||
$img_mark = $this->_createEmptyWatermark();
|
||||
$img_mark = $this->_addImageWatermark($mark, $img_mark);
|
||||
|
||||
$this->_createMarkedImage($img_mark, $type, 30);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Public int getMarkedImage
|
||||
* Returns the final image
|
||||
*/
|
||||
public function getMarkedImage() {
|
||||
if ($this->imageCreated == false) {
|
||||
$this->addWatermark($this->version);
|
||||
}
|
||||
return $this->marked_image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set position of watermark on image
|
||||
* Return true on valid parameter, otherwise false
|
||||
*
|
||||
* @param string $newposition
|
||||
* @return bool
|
||||
*/
|
||||
public function setPosition($newposition) {
|
||||
$valid_positions = array(
|
||||
"TL", "TM", "TR", "CL", "C", "CR", "BL", "BM", "BR", "RND"
|
||||
);
|
||||
|
||||
$newposition = strtoupper($newposition);
|
||||
|
||||
if (in_array($newposition, $valid_positions)) {
|
||||
if ($newposition == "RND") {
|
||||
$newposition = $valid_positions[rand(0, sizeof($valid_positions) - 2)];
|
||||
}
|
||||
$this->position = $newposition;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Set a fixed color for text watermarks
|
||||
* Return true on valid parameter, otherwise false
|
||||
*
|
||||
* @param array $color
|
||||
* @return bool
|
||||
*/
|
||||
public function setFixedColor($color) {
|
||||
$text_color = array();
|
||||
if (is_array($color) and sizeof($color) == 3) {
|
||||
$text_color["r"] = $color[0];
|
||||
$text_color["g"] = $color[1];
|
||||
$text_color["b"] = $color[2];
|
||||
} elseif (preg_match('/^#?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i', $color, $matches)) {
|
||||
$text_color["r"] = hexdec($matches[1]);
|
||||
$text_color["g"] = hexdec($matches[2]);
|
||||
$text_color["b"] = hexdec($matches[3]);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
foreach (array("r", "g", "b") as $key) {
|
||||
if (!array_key_exists($key, $text_color) or $text_color[$key] < 0 or $text_color[$key] > 255) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$this->fixedColor = $text_color;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function _die_error($errmsg) {
|
||||
die($errmsg);
|
||||
}
|
||||
|
||||
protected function _getTextSizes($text) {
|
||||
$act_scale = 0;
|
||||
$act_font = 0;
|
||||
|
||||
$marklength = strlen($text);
|
||||
$scale = ($this->orientation == "H") ? $this->width : $this->height; // Define maximum length of complete mark
|
||||
$char_widthmax = intval(($scale / $marklength) - 0.5); // Maximum character length in watermark
|
||||
|
||||
for ($size = 5; $size >= 1; $size--) {
|
||||
$box_w = imagefontwidth($size);
|
||||
$box_h = imagefontheight($size);
|
||||
$box_spacer_w = 0;
|
||||
$box_spacer_h = 0;
|
||||
|
||||
if ($this->orientation == "H") {
|
||||
$box_h *= 2;
|
||||
$box_w *= 1.75;
|
||||
$box_w *= $marklength;
|
||||
$box_w += intval($this->width * 0.05);
|
||||
$box_spacer_w = intval($this->width * 0.05);
|
||||
$box_spacer_h = intval($this->height * 0.01);
|
||||
} else {
|
||||
$box_w *= 3;
|
||||
$box_h *= 1.1;
|
||||
$box_h *= $marklength;
|
||||
$box_spacer_h = intval($this->height * 0.05);
|
||||
$box_spacer_w = intval($this->width * 0.01);
|
||||
}
|
||||
|
||||
$box_scale = ($this->orientation == "H") ? $box_w + $box_spacer_w : $box_h + $box_spacer_h;
|
||||
|
||||
if ($box_scale < $scale && $box_scale > $act_scale) { $act_font = $size; $act_scale = $box_scale; }
|
||||
}
|
||||
|
||||
return array(
|
||||
"fontsize" => $act_font,
|
||||
"box_w" => $box_w,
|
||||
"box_h" => $box_h,
|
||||
"spacer_w" => $box_spacer_w,
|
||||
"spacer_h" => $box_spacer_h
|
||||
);
|
||||
}
|
||||
|
||||
protected function _getImageSizes($res) {
|
||||
// Check if the overlay image is bigger than the main image
|
||||
|
||||
if (@imagesx($res) > $this->width || @imagesy($res) > $this->height) {
|
||||
// Need to resize the overlay image
|
||||
$box_h = $box_w = 0;
|
||||
$box_spacer_h = $box_spacer_w = 0;
|
||||
if (imagesx($res) > imagesy($res)) {
|
||||
$box_w = $this->width;
|
||||
$box_h = intval((imagesy($res) / (imagesx($res) / $this->width)) + 0.5);
|
||||
$box_spacer_h = intval(($this->height - $box_h) / 2);
|
||||
} else {
|
||||
$box_h = $this->height;
|
||||
$box_w = intval((imagesx($res) / (imagesy($res) / $this->height)) + 0.5);
|
||||
$box_spacer_w = intval(($this->width - $box_w) / 2);
|
||||
}
|
||||
} else {
|
||||
$box_spacer_h = $box_spacer_w = 0;
|
||||
$box_h = imagesy($res);
|
||||
$box_w = imagesx($res);
|
||||
}
|
||||
return array(
|
||||
"box_w" => $box_w,
|
||||
"box_h" => $box_h,
|
||||
"spacer_w" => $box_spacer_w,
|
||||
"spacer_h" => $box_spacer_h
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
protected function _getChunk() {
|
||||
$chunk = imagecreatetruecolor($this->sizes["box_w"], $this->sizes["box_h"]);
|
||||
imagecopy(
|
||||
$chunk,
|
||||
$this->image,
|
||||
0,
|
||||
0,
|
||||
$this->offset_x,
|
||||
$this->offset_y,
|
||||
$this->sizes["box_w"],
|
||||
$this->sizes["box_h"]
|
||||
);
|
||||
return $chunk;
|
||||
}
|
||||
|
||||
protected function _createEmptyWatermark() {
|
||||
return imagecreatetruecolor($this->sizes["box_w"], $this->sizes["box_h"]);
|
||||
//return imagecreate($this->sizes["box_w"], $this->sizes["box_h"]);
|
||||
}
|
||||
|
||||
protected function _addTextWatermark($mark, $img_mark, $chunk) {
|
||||
imagetruecolortopalette($chunk, true, 65535);
|
||||
$text_color = array("r" => 0, "g" => 0, "b" => 0);
|
||||
|
||||
if (is_array($this->fixedColor)) {
|
||||
$text_color = $this->fixedColor;
|
||||
} else {
|
||||
// Search color for overlay text
|
||||
for($x = 0; $x <= $this->sizes["box_w"]; $x++) {
|
||||
for ($y = 0; $y <= $this->sizes["box_h"]; $y++) {
|
||||
$colors = imagecolorsforindex($chunk, imagecolorat($chunk, $x, $y));
|
||||
$text_color["r"] += $colors["red"];
|
||||
$text_color["r"] /= 2;
|
||||
$text_color["g"] += $colors["green"];
|
||||
$text_color["g"] /= 2;
|
||||
$text_color["b"] += $colors["blue"];
|
||||
$text_color["b"] /= 2;
|
||||
}
|
||||
}
|
||||
$text_color["r"] = $text_color["r"] < 128 ? $text_color["r"] + 128 : $text_color["r"] - 128;
|
||||
$text_color["g"] = $text_color["g"] < 128 ? $text_color["g"] + 128 : $text_color["g"] - 128;
|
||||
$text_color["r"] = $text_color["r"] < 128 ? $text_color["r"] + 128 : $text_color["r"] - 128;
|
||||
}
|
||||
// Choose transparent color for watermark
|
||||
$mark_bg = imagecolorallocate( $img_mark,
|
||||
($text_color["r"] > 128 ? 10 : 240),
|
||||
($text_color["g"] > 128 ? 10 : 240),
|
||||
($text_color["b"] > 128 ? 10 : 240));
|
||||
|
||||
// Choose text color for watermark
|
||||
$mark_col = imagecolorallocate($img_mark, $text_color["r"], $text_color["g"], $text_color["b"]);
|
||||
|
||||
// Fill watermark with transparent color
|
||||
imagefill($img_mark, 0, 0, $mark_bg);
|
||||
imagecolortransparent($img_mark, $mark_bg);
|
||||
|
||||
// Add text to watermark
|
||||
if ($this->orientation == "H") {
|
||||
imagestring($img_mark, $this->sizes["fontsize"], 1, 0, $mark, $mark_col);
|
||||
} else {
|
||||
imagestringup($img_mark, $this->sizes["fontsize"], 0, $this->sizes["box_h"] - 5, $mark, $mark_col);
|
||||
}
|
||||
|
||||
return $img_mark;
|
||||
}
|
||||
|
||||
protected function _addImageWatermark($mark, $img_mark) {
|
||||
$transparent_color_idx = imagecolortransparent($mark);
|
||||
if ($transparent_color_idx >= 0) $transparent_color = imagecolorsforindex($mark, imagecolortransparent($mark));
|
||||
imagecopy($img_mark, $mark, 0, 0, 0, 0, imagesx($mark), imagesy($mark));
|
||||
if ($transparent_color_idx >= 0) {
|
||||
$trans;
|
||||
if (function_exists("imagecolorallocatealpha")) {
|
||||
$trans = imagecolorallocatealpha(
|
||||
$img_mark,
|
||||
$transparent_color["red"],
|
||||
$transparent_color["green"],
|
||||
$transparent_color["blue"],
|
||||
127
|
||||
);
|
||||
} else {
|
||||
$trans = imagecolorallocate(
|
||||
$img_mark,
|
||||
$transparent_color["red"],
|
||||
$transparent_color["green"],
|
||||
$transparent_color["blue"]
|
||||
);
|
||||
}
|
||||
imagecolortransparent($img_mark, $trans);
|
||||
}
|
||||
|
||||
return $img_mark;
|
||||
}
|
||||
|
||||
protected function _createMarkedImage($img_mark, $type, $pct) {
|
||||
// Create marked image (original + watermark)
|
||||
$this->marked_image = imagecreatetruecolor($this->width, $this->height);
|
||||
imagecopy($this->marked_image, $this->image, 0, 0, 0, 0, $this->width, $this->height);
|
||||
if ($type == 'TEXT') {
|
||||
imagecopymerge(
|
||||
$this->marked_image,
|
||||
$img_mark,
|
||||
$this->offset_x,
|
||||
$this->offset_y,
|
||||
0,
|
||||
0,
|
||||
$this->sizes["box_w"],
|
||||
$this->sizes["box_h"],
|
||||
$pct
|
||||
);
|
||||
$this->imageCreated = true;
|
||||
} elseif ($type == 'IMAGE') {
|
||||
if ($this->gd_version >= 2) { // GD2: Should be the easy way
|
||||
imagealphablending($this->marked_image, true);
|
||||
|
||||
imagecopy(
|
||||
$this->marked_image,
|
||||
$img_mark,
|
||||
$this->offset_x,
|
||||
$this->offset_y,
|
||||
0,
|
||||
0,
|
||||
$this->sizes["box_w"],
|
||||
$this->sizes["box_h"]
|
||||
);
|
||||
} else {
|
||||
imagecopymerge(
|
||||
$this->marked_image,
|
||||
$img_mark,
|
||||
$this->offset_x,
|
||||
$this->offset_y,
|
||||
0,
|
||||
0,
|
||||
$this->sizes["box_w"],
|
||||
$this->sizes["box_h"],
|
||||
$pct
|
||||
);
|
||||
}
|
||||
|
||||
$this->imageCreated = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function _getOffsets() {
|
||||
$width_mark = $this->sizes["box_w"] + $this->sizes["spacer_w"];
|
||||
$height_mark = $this->sizes["box_h"] + $this->sizes["spacer_h"];
|
||||
$width_left = $this->width - $width_mark;
|
||||
$height_left = $this->height - $height_mark;
|
||||
|
||||
switch ($this->position) {
|
||||
case "TL": // Top Left
|
||||
$this->offset_x = $width_left >= 5 ? 5 : $width_left;
|
||||
$this->offset_y = $height_left >= 5 ? 5 : $height_left;
|
||||
break;
|
||||
case "TM": // Top middle
|
||||
$this->offset_x = intval(($this->width - $width_mark) / 2);
|
||||
$this->offset_y = $height_left >= 5 ? 5 : $height_left;
|
||||
break;
|
||||
case "TR": // Top right
|
||||
$this->offset_x = $this->width - $width_mark;
|
||||
$this->offset_y = $height_left >= 5 ? 5 : $height_left;
|
||||
break;
|
||||
case "CL": // Center left
|
||||
$this->offset_x = $width_left >= 5 ? 5 : $width_left;
|
||||
$this->offset_y = intval(($this->height - $height_mark) / 2);
|
||||
break;
|
||||
default:
|
||||
case "C": // Center (the default)
|
||||
$this->offset_x = intval(($this->width - $width_mark) / 2);
|
||||
$this->offset_y = intval(($this->height - $height_mark) / 2);
|
||||
break;
|
||||
case "CR": // Center right
|
||||
$this->offset_x = $this->width - $width_mark;
|
||||
$this->offset_y = intval(($this->height - $height_mark) / 2);
|
||||
break;
|
||||
case "BL": // Bottom left
|
||||
$this->offset_x = $width_left >= 5 ? 5 : $width_left;
|
||||
$this->offset_y = $this->height - $height_mark;
|
||||
break;
|
||||
case "BM": // Bottom middle
|
||||
$this->offset_x = intval(($this->width - $width_mark) / 2);
|
||||
$this->offset_y = $this->height - $height_mark;
|
||||
break;
|
||||
case "BR": // Bottom right
|
||||
$this->offset_x = $this->width - $width_mark;
|
||||
$this->offset_y = $this->height - $height_mark;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Takes a path to an image or a php image resource as the only argument
|
||||
* Returns image type and the appropriate image resource
|
||||
*
|
||||
* @param object $res
|
||||
* @return array
|
||||
*/
|
||||
protected function _getImage($res) {
|
||||
if (intval(@imagesx($res)) > 0) {
|
||||
$img = $res;
|
||||
} else {
|
||||
$imginfo = getimagesize($res);
|
||||
|
||||
switch($imginfo[2]) { // Determine type
|
||||
case 1:
|
||||
$type = "GIF";
|
||||
if (function_exists("imagecreatefromgif")) {
|
||||
$img = imagecreatefromgif($res);
|
||||
} else {
|
||||
die("Unsupported image type: $type");
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
$type = "JPG";
|
||||
if (function_exists("imagecreatefromjpeg")) {
|
||||
$img = imagecreatefromjpeg($res);
|
||||
} else {
|
||||
die("Unsupported image type: $type");
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
$type = "PNG";
|
||||
if (function_exists("imagecreatefrompng")) {
|
||||
$img = imagecreatefrompng($res);
|
||||
} else {
|
||||
die("Unsupported image type: $type");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return array($type, $img);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
Loading…
Reference in a new issue