1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-07-05 07:54:24 +03:00
ifhub.club/engine/lib/external/LiveImage/Image.php

689 lines
17 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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='';
/**
* Quality of output JPG image
*
* @var int
*/
protected $jpg_quality = null;
/**
* 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',
6 => 'Failed image resource 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':
case "image/x-png":
$tmp=imagecreatefrompng($file);
$this->format='png';
break;
case 'image/gif':
$tmp=imagecreatefromgif($file);
$this->format='gif';
break;
case "image/pjpeg":
case "image/jpeg":
case "image/jpg":
$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,$alfa=true) {
$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);
}
$tmp=($this->truecolor)
? imagecreatetruecolor($width,$height)
: imagecreate($width,$height);
/**
* Если темп-изображение не создано, ставим отметку об ошикбе
*/
if(!$tmp) {
$this->set_last_error(1);
return false;
}
if($this->format=='gif') {
imagealphablending($this->image, false);
$ct = @imagecolortransparent($this->image);
$color_tran = @imagecolorsforindex($this->image, $ct);
if($color_tran) {
$ct2 = imagecolorexact($tmp, $color_tran['red'], $color_tran['green'], $color_tran['blue']);
imagefill($tmp,0,0,$ct2);
}
/**
* Определяем функцию, которой будет выполнен ресайз изображения
*/
$sResizeFunction = 'imagecopyresampled';
if(!function_exists($sResizeFunction)) $sResizeFunction = 'imagecopyresized';
if(isset($ct) and $ct!=-1) $sResizeFunction = 'imagecopyresized';
if(!@$sResizeFunction($tmp,$this->image,0,0,0,0,$width,$height,$this->width,$this->height)) {
imagedestroy($tmp);
return false;
}
imagesavealpha($tmp, true);
if(isset($ct2)) imagecolortransparent($tmp, $ct2);
} else {
/**
* Регулируем альфа-канал, если не указано обработное
*/
if($alfa) {
@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->set_image($tmp);
return true;
}
/**
* Crop image
*
* @param int $width
* @param int $height
* @param int $start_width
* @param int $start_height
* @return mixed
*/
public function crop($width, $height, $start_width, $start_height) {
$tmp=($this->truecolor)
? imagecreatetruecolor($width,$height)
: imagecreate($width,$height);
/**
* Если темп-изображение не создано, ставим отметку об ошикбе
*/
if(!$tmp) {
$this->set_last_error(1);
return false;
}
if($this->format=='gif') {
imagealphablending($this->image, false);
$ct = @imagecolortransparent($this->image);
$color_tran = @imagecolorsforindex($this->image, $ct);
if($color_tran) {
$ct2 = imagecolorexact($tmp, $color_tran['red'], $color_tran['green'], $color_tran['blue']);
imagefill($tmp,0,0,$ct2);
}
/**
* Определяем функцию, которой будет выполнен ресайз изображения
*/
$sResizeFunction = 'imagecopyresampled';
if(!function_exists($sResizeFunction)) $sResizeFunction = 'imagecopyresized';
if(isset($ct) and $ct!=-1) $sResizeFunction = 'imagecopyresized';
if(!@$sResizeFunction($tmp,$this->image,0,0,0,0,$width,$height,$this->width,$this->height)) {
imagedestroy($tmp);
return false;
}
imagesavealpha($tmp, true);
if(isset($ct2)) imagecolortransparent($tmp, $ct2);
} else {
@imagesavealpha($tmp,true);
@imagealphablending($tmp,false);
if(!imagecopyresampled($tmp,$this->image,0,0,$start_width,$start_height,$width,$height,$width,$height)) {
imagedestroy($tmp);
return false;
}
}
imagedestroy($this->image);
$this->set_image($tmp);
return true;
}
/**
* Return image object
*
* @return mixed
*/
public function get_image() {
return $this->image;
}
/**
* Add new image object to current handler
*
* @param resource $image_res
* @return bool
*
* @todo Find format of given image
*/
public function set_image($image_res) {
if (intval(@imagesx($image_res)) > 0) {
$this->image=$image_res;
$this->width=imagesx($image_res);
$this->height=imagesy($image_res);
return true;
}
$this->set_last_error(6);
return false;
}
/**
* 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'];
}
/**
* Set JPG output quality
*
* @param int $quality
* @return null
*/
public function set_jpg_quality($quality=null) {
$this->jpg_quality = $quality;
}
/**
* 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['locate'],$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['locate']);
/// Наносим надпись водянного знака
$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['locate'], $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':
@imagesavealpha($this->image,true);
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,$this->jpg_quality);
}
break;
case 'gif':
if(!$file) {
header("Content-type: image/gif");
imagegif($this->image);
} else {
imagegif($this->image,$file);
}
break;
}
}
public function paste_image($file,$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 || !($size=getimagesize($file))) {
$this->set_last_error(3);
return false;
}
/**
* Определяем тип файла изображения
*/
switch ($size['mime']) {
case 'image/png':
case "image/x-png":
$tmp=imagecreatefrompng($file);
break;
case 'image/gif':
$tmp=imagecreatefromgif($file);
break;
case "image/pjpeg":
case "image/jpeg":
case "image/jpg":
$tmp=imagecreatefromjpeg($file);
break;
default:
$this->set_last_error(5);
return false;
}
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);
}
$dst_w=$dst_w<0 ? imagesx($tmp) : $dst_w;
$dst_h=$dst_h<0 ? imagesy($tmp) : $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=imagecopyresampled($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 = $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;
}
}
?>