Орла
Области
Компаний
Пользователи
Галерея
Фиксированные новости
Орла
Отзывы о фирмах
Тарифы
Пользователи
Области
Банкоматы
Торговые точки
Доска объявлений
Курсы валют
Скидки
организации Орла
организации области
товары
сайты
сайты Орел
Данные
Разделы
Поиск
Поиск запросы
Статистика
Показы каталога организаций
Статистика клиенты
Пользователи
Сайты
Управление сайтом
Анкета
Аптеки
Афиша
Афиша новая
Баннеры
Бизнес >
Викторина
Голосование
Гость на сайте
Истории
Календарь событий
Каталоги >
Конкурс красоты
Конкурс аудио
Консультации
Меню
Новое на сайте
Новости >
Организации >
Программа ТВ
Публикации
Разделы сайта
Рассылка
Рестораны
Секрет фирмы >
Сервисы >
Ссылки
Тесты
Файловый менеджер
Форум
Фотогалерея
Обратная связь
Недвижимость
Новый год
Тексты
Пользователи
Юридический рейтинг
Отзывы на товары
Бан пользователей
Жалобы
Новые тесты
Коронавирус
Файловый менеджер
Имя файла
SimpleImage.php
Содержимое
<?php /** * @package SimpleImage class * @version 2.6.0 * @author Cory LaViska for A Beautiful Site, LLC (http://www.abeautifulsite.net/) * @author Nazar Mokrynskyi <nazar@mokrynskyi.com> - merging of forks, namespace support, PhpDoc editing, adaptive_resize() method, other fixes * @license This software is licensed under the MIT license: http://opensource.org/licenses/MIT * @copyright A Beautiful Site, LLC * */ namespace abeautifulsite; use Exception; /** * Class SimpleImage * This class makes image manipulation in PHP as simple as possible. * @package SimpleImage * */ class SimpleImage { /** * @var int Default output image quality * */ public $quality = 80; protected $image, $filename, $original_info, $width, $height, $imagestring; /** * Create instance and load an image, or create an image from scratch * * @param null|string $filename Path to image file (may be omitted to create image from scratch) * @param int $width Image width (is used for creating image from scratch) * @param int|null $height If omitted - assumed equal to $width (is used for creating image from scratch) * @param null|string $color Hex color string, array(red, green, blue) or array(red, green, blue, alpha). * Where red, green, blue - integers 0-255, alpha - integer 0-127<br> * (is used for creating image from scratch) * * @return SimpleImage * @throws Exception * */ function __construct($filename = null, $width = null, $height = null, $color = null) { if ($filename) { $this->load($filename); } elseif ($width) { $this->create($width, $height, $color); } return $this; } /** * Destroy image resource * */ function __destruct() { if( $this->image !== null && get_resource_type($this->image) === 'gd' ) { imagedestroy($this->image); } } /** * Adaptive resize * * This function has been deprecated and will be removed in an upcoming release. Please * update your code to use the `thumbnail()` method instead. The arguments for both * methods are exactly the same. * * @param int $width * @param int|null $height If omitted - assumed equal to $width * * @return SimpleImage * */ function adaptive_resize($width, $height = null) { return $this->thumbnail($width, $height); } /** * Rotates and/or flips an image automatically so the orientation will be correct (based on exif 'Orientation') * * @return SimpleImage * */ function auto_orient() { if(isset($this->original_info['exif']['Orientation'])) { switch ($this->original_info['exif']['Orientation']) { case 1: // Do nothing break; case 2: // Flip horizontal $this->flip('x'); break; case 3: // Rotate 180 counterclockwise $this->rotate(-180); break; case 4: // vertical flip $this->flip('y'); break; case 5: // Rotate 90 clockwise and flip vertically $this->flip('y'); $this->rotate(90); break; case 6: // Rotate 90 clockwise $this->rotate(90); break; case 7: // Rotate 90 clockwise and flip horizontally $this->flip('x'); $this->rotate(90); break; case 8: // Rotate 90 counterclockwise $this->rotate(-90); break; } } return $this; } /** * Best fit (proportionally resize to fit in specified width/height) * * Shrink the image proportionally to fit inside a $width x $height box * * @param int $max_width * @param int $max_height * * @return SimpleImage * */ function best_fit($max_width, $max_height) { // If it already fits, there's nothing to do if ($this->width <= $max_width && $this->height <= $max_height) { return $this; } // Determine aspect ratio $aspect_ratio = $this->height / $this->width; // Make width fit into new dimensions if ($this->width > $max_width) { $width = $max_width; $height = $width * $aspect_ratio; } else { $width = $this->width; $height = $this->height; } // Make height fit into new dimensions if ($height > $max_height) { $height = $max_height; $width = $height / $aspect_ratio; } return $this->resize($width, $height); } /** * Blur * * @param string $type selective|gaussian * @param int $passes Number of times to apply the filter * * @return SimpleImage * */ function blur($type = 'selective', $passes = 1) { switch (strtolower($type)) { case 'gaussian': $type = IMG_FILTER_GAUSSIAN_BLUR; break; default: $type = IMG_FILTER_SELECTIVE_BLUR; break; } for ($i = 0; $i < $passes; $i++) { imagefilter($this->image, $type); } return $this; } /** * Brightness * * @param int $level Darkest = -255, lightest = 255 * * @return SimpleImage * */ function brightness($level) { imagefilter($this->image, IMG_FILTER_BRIGHTNESS, $this->keep_within($level, -255, 255)); return $this; } /** * Contrast * * @param int $level Min = -100, max = 100 * * @return SimpleImage * * */ function contrast($level) { imagefilter($this->image, IMG_FILTER_CONTRAST, $this->keep_within($level, -100, 100)); return $this; } /** * Colorize * * @param string $color Hex color string, array(red, green, blue) or array(red, green, blue, alpha). * Where red, green, blue - integers 0-255, alpha - integer 0-127 * @param float|int $opacity 0-1 * * @return SimpleImage * */ function colorize($color, $opacity) { $rgba = $this->normalize_color($color); $alpha = $this->keep_within(127 - (127 * $opacity), 0, 127); imagefilter($this->image, IMG_FILTER_COLORIZE, $this->keep_within($rgba['r'], 0, 255), $this->keep_within($rgba['g'], 0, 255), $this->keep_within($rgba['b'], 0, 255), $alpha); return $this; } /** * Create an image from scratch * * @param int $width Image width * @param int|null $height If omitted - assumed equal to $width * @param null|string $color Hex color string, array(red, green, blue) or array(red, green, blue, alpha). * Where red, green, blue - integers 0-255, alpha - integer 0-127 * * @return SimpleImage * */ function create($width, $height = null, $color = null) { $height = $height ?: $width; $this->width = $width; $this->height = $height; $this->image = imagecreatetruecolor($width, $height); $this->original_info = array( 'width' => $width, 'height' => $height, 'orientation' => $this->get_orientation(), 'exif' => null, 'format' => 'png', 'mime' => 'image/png' ); if ($color) { $this->fill($color); } return $this; } /** * Crop an image * * @param int $x1 Left * @param int $y1 Top * @param int $x2 Right * @param int $y2 Bottom * * @return SimpleImage * */ function crop($x1, $y1, $x2, $y2) { // Determine crop size if ($x2 < $x1) { list($x1, $x2) = array($x2, $x1); } if ($y2 < $y1) { list($y1, $y2) = array($y2, $y1); } $crop_width = $x2 - $x1; $crop_height = $y2 - $y1; // Perform crop $new = imagecreatetruecolor($crop_width, $crop_height); imagealphablending($new, false); imagesavealpha($new, true); imagecopyresampled($new, $this->image, 0, 0, $x1, $y1, $crop_width, $crop_height, $crop_width, $crop_height); // Update meta data $this->width = $crop_width; $this->height = $crop_height; $this->image = $new; return $this; } /** * Desaturate * * @param int $percentage Level of desaturization. * * @return SimpleImage * */ function desaturate($percentage = 100) { // Determine percentage $percentage = $this->keep_within($percentage, 0, 100); if( $percentage === 100 ) { imagefilter($this->image, IMG_FILTER_GRAYSCALE); } else { // Make a desaturated copy of the image $new = imagecreatetruecolor($this->width, $this->height); imagealphablending($new, false); imagesavealpha($new, true); imagecopy($new, $this->image, 0, 0, 0, 0, $this->width, $this->height); imagefilter($new, IMG_FILTER_GRAYSCALE); // Merge with specified percentage $this->imagecopymerge_alpha($this->image, $new, 0, 0, 0, 0, $this->width, $this->height, $percentage); imagedestroy($new); } return $this; } /** * Edge Detect * * @return SimpleImage * */ function edges() { imagefilter($this->image, IMG_FILTER_EDGEDETECT); return $this; } /** * Emboss * * @return SimpleImage * */ function emboss() { imagefilter($this->image, IMG_FILTER_EMBOSS); return $this; } /** * Fill image with color * * @param string $color Hex color string, array(red, green, blue) or array(red, green, blue, alpha). * Where red, green, blue - integers 0-255, alpha - integer 0-127 * * @return SimpleImage * */ function fill($color = '#000000') { $rgba = $this->normalize_color($color); $fill_color = imagecolorallocatealpha($this->image, $rgba['r'], $rgba['g'], $rgba['b'], $rgba['a']); imagealphablending($this->image, false); imagesavealpha($this->image, true); imagefilledrectangle($this->image, 0, 0, $this->width, $this->height, $fill_color); return $this; } /** * Fit to height (proportionally resize to specified height) * * @param int $height * * @return SimpleImage * */ function fit_to_height($height) { $aspect_ratio = $this->height / $this->width; $width = $height / $aspect_ratio; return $this->resize($width, $height); } /** * Fit to width (proportionally resize to specified width) * * @param int $width * * @return SimpleImage * */ function fit_to_width($width) { $aspect_ratio = $this->height / $this->width; $height = $width * $aspect_ratio; return $this->resize($width, $height); } /** * Flip an image horizontally or vertically * * @param string $direction x|y * * @return SimpleImage * */ function flip($direction) { $new = imagecreatetruecolor($this->width, $this->height); imagealphablending($new, false); imagesavealpha($new, true); switch (strtolower($direction)) { case 'y': for ($y = 0; $y < $this->height; $y++) { imagecopy($new, $this->image, 0, $y, 0, $this->height - $y - 1, $this->width, 1); } break; default: for ($x = 0; $x < $this->width; $x++) { imagecopy($new, $this->image, $x, 0, $this->width - $x - 1, 0, 1, $this->height); } break; } $this->image = $new; return $this; } /** * Get the current height * * @return int * */ function get_height() { return $this->height; } /** * Get the current orientation * * @return string portrait|landscape|square * */ function get_orientation() { if (imagesx($this->image) > imagesy($this->image)) { return 'landscape'; } if (imagesx($this->image) < imagesy($this->image)) { return 'portrait'; } return 'square'; } /** * Get info about the original image * * @return array <pre> array( * width => 320, * height => 200, * orientation => ['portrait', 'landscape', 'square'], * exif => array(...), * mime => ['image/jpeg', 'image/gif', 'image/png'], * format => ['jpeg', 'gif', 'png'] * )</pre> * */ function get_original_info() { return $this->original_info; } /** * Get the current width * * @return int * */ function get_width() { return $this->width; } /** * Invert * * @return SimpleImage * */ function invert() { imagefilter($this->image, IMG_FILTER_NEGATE); return $this; } /** * Load an image * * @param string $filename Path to image file * * @return SimpleImage * @throws Exception * */ function load($filename) { // Require GD library if (!extension_loaded('gd')) { throw new Exception('Required extension GD is not loaded.'); } $this->filename = $filename; return $this->get_meta_data(); } /** * Load a base64 string as image * * @param string $filename base64 string * * @return SimpleImage * */ function load_base64($base64string) { if (!extension_loaded('gd')) { throw new Exception('Required extension GD is not loaded.'); } //remove data URI scheme and spaces from base64 string then decode it $this->imagestring = base64_decode(str_replace(' ', '+',preg_replace('#^data:image/[^;]+;base64,#', '', $base64string))); $this->image = imagecreatefromstring($this->imagestring); return $this->get_meta_data(); } /** * Mean Remove * * @return SimpleImage * */ function mean_remove() { imagefilter($this->image, IMG_FILTER_MEAN_REMOVAL); return $this; } /** * Changes the opacity level of the image * * @param float|int $opacity 0-1 * * @throws Exception * */ function opacity($opacity) { // Determine opacity $opacity = $this->keep_within($opacity, 0, 1) * 100; // Make a copy of the image $copy = imagecreatetruecolor($this->width, $this->height); imagealphablending($copy, false); imagesavealpha($copy, true); imagecopy($copy, $this->image, 0, 0, 0, 0, $this->width, $this->height); // Create transparent layer $this->create($this->width, $this->height, array(0, 0, 0, 127)); // Merge with specified opacity $this->imagecopymerge_alpha($this->image, $copy, 0, 0, 0, 0, $this->width, $this->height, $opacity); imagedestroy($copy); return $this; } /** * Outputs image without saving * * @param null|string $format If omitted or null - format of original file will be used, may be gif|jpg|png * @param int|null $quality Output image quality in percents 0-100 * * @throws Exception * */ function output($format = null, $quality = null) { // Determine quality $quality = $quality ?: $this->quality; // Determine mimetype switch (strtolower($format)) { case 'gif': $mimetype = 'image/gif'; break; case 'jpeg': case 'jpg': imageinterlace($this->image, true); $mimetype = 'image/jpeg'; break; case 'png': $mimetype = 'image/png'; break; default: $info = (empty($this->imagestring)) ? getimagesize($this->filename) : getimagesizefromstring($this->imagestring); $mimetype = $info['mime']; unset($info); break; } // Output the image header('Content-Type: '.$mimetype); switch ($mimetype) { case 'image/gif': imagegif($this->image); break; case 'image/jpeg': imageinterlace($this->image, true); imagejpeg($this->image, null, round($quality)); break; case 'image/png': imagepng($this->image, null, round(9 * $quality / 100)); break; default: throw new Exception('Unsupported image format: '.$this->filename); break; } } /** * Outputs image as data base64 to use as img src * * @param null|string $format If omitted or null - format of original file will be used, may be gif|jpg|png * @param int|null $quality Output image quality in percents 0-100 * * @return string * @throws Exception * */ function output_base64($format = null, $quality = null) { // Determine quality $quality = $quality ?: $this->quality; // Determine mimetype switch (strtolower($format)) { case 'gif': $mimetype = 'image/gif'; break; case 'jpeg': case 'jpg': imageinterlace($this->image, true); $mimetype = 'image/jpeg'; break; case 'png': $mimetype = 'image/png'; break; default: $info = getimagesize($this->filename); $mimetype = $info['mime']; unset($info); break; } // Output the image ob_start(); switch ($mimetype) { case 'image/gif': imagegif($this->image); break; case 'image/jpeg': imagejpeg($this->image, null, round($quality)); break; case 'image/png': imagepng($this->image, null, round(9 * $quality / 100)); break; default: throw new Exception('Unsupported image format: '.$this->filename); break; } $image_data = ob_get_contents(); ob_end_clean(); // Returns formatted string for img src return 'data:'.$mimetype.';base64,'.base64_encode($image_data); } /** * Overlay * * Overlay an image on top of another, works with 24-bit PNG alpha-transparency * * @param string $overlay An image filename or a SimpleImage object * @param string $position center|top|left|bottom|right|top left|top right|bottom left|bottom right * @param float|int $opacity Overlay opacity 0-1 * @param int $x_offset Horizontal offset in pixels * @param int $y_offset Vertical offset in pixels * * @return SimpleImage * */ function overlay($overlay, $position = 'center', $opacity = 1, $x_offset = 0, $y_offset = 0) { // Load overlay image if( !($overlay instanceof SimpleImage) ) { $overlay = new SimpleImage($overlay); } // Convert opacity $opacity = $opacity * 100; // Determine position switch (strtolower($position)) { case 'top left': $x = 0 + $x_offset; $y = 0 + $y_offset; break; case 'top right': $x = $this->width - $overlay->width + $x_offset; $y = 0 + $y_offset; break; case 'top': $x = ($this->width / 2) - ($overlay->width / 2) + $x_offset; $y = 0 + $y_offset; break; case 'bottom left': $x = 0 + $x_offset; $y = $this->height - $overlay->height + $y_offset; break; case 'bottom right': $x = $this->width - $overlay->width + $x_offset; $y = $this->height - $overlay->height + $y_offset; break; case 'bottom': $x = ($this->width / 2) - ($overlay->width / 2) + $x_offset; $y = $this->height - $overlay->height + $y_offset; break; case 'left': $x = 0 + $x_offset; $y = ($this->height / 2) - ($overlay->height / 2) + $y_offset; break; case 'right': $x = $this->width - $overlay->width + $x_offset; $y = ($this->height / 2) - ($overlay->height / 2) + $y_offset; break; case 'center': default: $x = ($this->width / 2) - ($overlay->width / 2) + $x_offset; $y = ($this->height / 2) - ($overlay->height / 2) + $y_offset; break; } // Perform the overlay $this->imagecopymerge_alpha($this->image, $overlay->image, $x, $y, 0, 0, $overlay->width, $overlay->height, $opacity); return $this; } /** * Pixelate * * @param int $block_size Size in pixels of each resulting block * * @return SimpleImage * */ function pixelate($block_size = 10) { imagefilter($this->image, IMG_FILTER_PIXELATE, $block_size, true); return $this; } /** * Resize an image to the specified dimensions * * @param int $width * @param int $height * * @return SimpleImage * */ function resize($width, $height) { // Generate new GD image $new = imagecreatetruecolor($width, $height); if( $this->original_info['format'] === 'gif' ) { // Preserve transparency in GIFs $transparent_index = imagecolortransparent($this->image); $palletsize = imagecolorstotal($this->image); if ($transparent_index >= 0 && $transparent_index < $palletsize) { $transparent_color = imagecolorsforindex($this->image, $transparent_index); $transparent_index = imagecolorallocate($new, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']); imagefill($new, 0, 0, $transparent_index); imagecolortransparent($new, $transparent_index); } } else { // Preserve transparency in PNGs (benign for JPEGs) imagealphablending($new, false); imagesavealpha($new, true); } // Resize imagecopyresampled($new, $this->image, 0, 0, 0, 0, $width, $height, $this->width, $this->height); // Update meta data $this->width = $width; $this->height = $height; $this->image = $new; return $this; } /** * Rotate an image * * @param int $angle 0-360 * @param string $bg_color Hex color string, array(red, green, blue) or array(red, green, blue, alpha). * Where red, green, blue - integers 0-255, alpha - integer 0-127 * * @return SimpleImage * */ function rotate($angle, $bg_color = '#000000') { // Perform the rotation $rgba = $this->normalize_color($bg_color); $bg_color = imagecolorallocatealpha($this->image, $rgba['r'], $rgba['g'], $rgba['b'], $rgba['a']); $new = imagerotate($this->image, -($this->keep_within($angle, -360, 360)), $bg_color); imagesavealpha($new, true); imagealphablending($new, true); // Update meta data $this->width = imagesx($new); $this->height = imagesy($new); $this->image = $new; return $this; } /** * Save an image * * The resulting format will be determined by the file extension. * * @param null|string $filename If omitted - original file will be overwritten * @param null|int $quality Output image quality in percents 0-100 * @param null|string $format The format to use; determined by file extension if null * * @return SimpleImage * @throws Exception * */ function save($filename = null, $quality = null, $format = null) { // Determine quality, filename, and format $quality = $quality ?: $this->quality; $filename = $filename ?: $this->filename; if( !$format ) { $format = $this->file_ext($filename) ?: $this->original_info['format']; } // Create the image switch (strtolower($format)) { case 'gif': $result = imagegif($this->image, $filename); break; case 'jpg': case 'jpeg': imageinterlace($this->image, true); $result = imagejpeg($this->image, $filename, round($quality)); break; case 'png': $result = imagepng($this->image, $filename, round(9 * $quality / 100)); break; default: throw new Exception('Unsupported format'); } if (!$result) { throw new Exception('Unable to save image: ' . $filename); } return $this; } /** * Sepia * * @return SimpleImage * */ function sepia() { imagefilter($this->image, IMG_FILTER_GRAYSCALE); imagefilter($this->image, IMG_FILTER_COLORIZE, 100, 50, 0); return $this; } /** * Sketch * * @return SimpleImage * */ function sketch() { imagefilter($this->image, IMG_FILTER_MEAN_REMOVAL); return $this; } /** * Smooth * * @param int $level Min = -10, max = 10 * * @return SimpleImage * */ function smooth($level) { imagefilter($this->image, IMG_FILTER_SMOOTH, $this->keep_within($level, -10, 10)); return $this; } /** * Add text to an image * * @param string $text * @param string $font_file * @param float|int $font_size * @param string|array $color * @param string $position * @param int $x_offset * @param int $y_offset * @param string|array $stroke_color * @param string $stroke_size * @param string $alignment * @param int $letter_spacing * * @return SimpleImage * @throws Exception * */ function text($text, $font_file, $font_size = 12, $color = '#000000', $position = 'center', $x_offset = 0, $y_offset = 0, $stroke_color = null, $stroke_size = null, $alignment = null, $letter_spacing = 0) { // todo - this method could be improved to support the text angle $angle = 0; // Determine text color if(is_array($color)) { foreach($color as $var) { $rgba = $this->normalize_color($var); $color_arr[] = imagecolorallocatealpha($this->image, $rgba['r'], $rgba['g'], $rgba['b'], $rgba['a']); } } else { $rgba = $this->normalize_color($color); $color_arr[] = imagecolorallocatealpha($this->image, $rgba['r'], $rgba['g'], $rgba['b'], $rgba['a']); } // Determine textbox size $box = imagettfbbox($font_size, $angle, $font_file, $text); if (!$box) { throw new Exception('Unable to load font: '.$font_file); } $box_width = abs($box[6] - $box[2]); $box_height = abs($box[7] - $box[1]); // Determine position switch (strtolower($position)) { case 'top left': $x = 0 + $x_offset; $y = 0 + $y_offset + $box_height; break; case 'top right': $x = $this->width - $box_width + $x_offset; $y = 0 + $y_offset + $box_height; break; case 'top': $x = ($this->width / 2) - ($box_width / 2) + $x_offset; $y = 0 + $y_offset + $box_height; break; case 'bottom left': $x = 0 + $x_offset; $y = $this->height - $box_height + $y_offset + $box_height; break; case 'bottom right': $x = $this->width - $box_width + $x_offset; $y = $this->height - $box_height + $y_offset + $box_height; break; case 'bottom': $x = ($this->width / 2) - ($box_width / 2) + $x_offset; $y = $this->height - $box_height + $y_offset + $box_height; break; case 'left': $x = 0 + $x_offset; $y = ($this->height / 2) - (($box_height / 2) - $box_height) + $y_offset; break; case 'right'; $x = $this->width - $box_width + $x_offset; $y = ($this->height / 2) - (($box_height / 2) - $box_height) + $y_offset; break; case 'center': default: $x = ($this->width / 2) - ($box_width / 2) + $x_offset; $y = ($this->height / 2) - (($box_height / 2) - $box_height) + $y_offset; break; } if($alignment === "left") { // Left aligned text $x = -($x * 2); } else if($alignment === "right") { // Right aligned text $dimensions = imagettfbbox($font_size, $angle, $font_file, $text); $alignment_offset = abs($dimensions[4] - $dimensions[0]); $x = -(($x * 2) + $alignment_offset); } // Add the text imagesavealpha($this->image, true); imagealphablending($this->image, true); if(isset($stroke_color) && isset($stroke_size)) { // Text with stroke if(is_array($color) || is_array($stroke_color)) { // Multi colored text and/or multi colored stroke if(is_array($stroke_color)) { foreach($stroke_color as $key => $var) { $rgba = $this->normalize_color($stroke_color[$key]); $stroke_color[$key] = imagecolorallocatealpha($this->image, $rgba['r'], $rgba['g'], $rgba['b'], $rgba['a']); } } else { $rgba = $this->normalize_color($stroke_color); $stroke_color = imagecolorallocatealpha($this->image, $rgba['r'], $rgba['g'], $rgba['b'], $rgba['a']); } $array_of_letters = str_split($text, 1); foreach($array_of_letters as $key => $var) { if($key > 0) { $dimensions = imagettfbbox($font_size, $angle, $font_file, $array_of_letters[$key - 1]); $x += abs($dimensions[4] - $dimensions[0]) + $letter_spacing; } // If the next letter is empty, we just move forward to the next letter if($var !== " ") { $this->imagettfstroketext($this->image, $font_size, $angle, $x, $y, current($color_arr), current($stroke_color), $stroke_size, $font_file, $var); // #000 is 0, black will reset the array so we write it this way if(next($color_arr) === false) { reset($color_arr); } // #000 is 0, black will reset the array so we write it this way if(next($stroke_color) === false) { reset($stroke_color); } } } } else { $rgba = $this->normalize_color($stroke_color); $stroke_color = imagecolorallocatealpha($this->image, $rgba['r'], $rgba['g'], $rgba['b'], $rgba['a']); $this->imagettfstroketext($this->image, $font_size, $angle, $x, $y, $color_arr[0], $stroke_color, $stroke_size, $font_file, $text); } } else { // Text without stroke if(is_array($color)) { // Multi colored text $array_of_letters = str_split($text, 1); foreach($array_of_letters as $key => $var) { if($key > 0) { $dimensions = imagettfbbox($font_size, $angle, $font_file, $array_of_letters[$key - 1]); $x += abs($dimensions[4] - $dimensions[0]) + $letter_spacing; } // If the next letter is empty, we just move forward to the next letter if($var !== " ") { imagettftext($this->image, $font_size, $angle, $x, $y, current($color_arr), $font_file, $var); // #000 is 0, black will reset the array so we write it this way if(next($color_arr) === false) { reset($color_arr); } } } } else { imagettftext($this->image, $font_size, $angle, $x, $y, $color_arr[0], $font_file, $text); } } return $this; } /** * Thumbnail * * This function attempts to get the image to as close to the provided dimensions as possible, and then crops the * remaining overflow (from the center) to get the image to be the size specified. Useful for generating thumbnails. * * @param int $width * @param int|null $height If omitted - assumed equal to $width * * @return SimpleImage * */ function thumbnail($width, $height = null) { // Determine height $height = $height ?: $width; // Determine aspect ratios $current_aspect_ratio = $this->height / $this->width; $new_aspect_ratio = $height / $width; // Fit to height/width if ($new_aspect_ratio > $current_aspect_ratio) { $this->fit_to_height($height); } else { $this->fit_to_width($width); } $left = floor(($this->width / 2) - ($width / 2)); $top = floor(($this->height / 2) - ($height / 2)); // Return trimmed image return $this->crop($left, $top, $width + $left, $height + $top); } /** * Returns the file extension of the specified file * * @param string $filename * * @return string * */ protected function file_ext($filename) { if (!preg_match('/\./', $filename)) { return ''; } return preg_replace('/^.*\./', '', $filename); } /** * Get meta data of image or base64 string * * @param string|null $imagestring If omitted treat as a normal image * * @return SimpleImage * @throws Exception * */ protected function get_meta_data() { //gather meta data if(empty($this->imagestring)) { $info = getimagesize($this->filename); switch ($info['mime']) { case 'image/gif': $this->image = imagecreatefromgif($this->filename); break; case 'image/jpeg': $this->image = imagecreatefromjpeg($this->filename); break; case 'image/png': $this->image = imagecreatefrompng($this->filename); break; default: throw new Exception('Invalid image: '.$this->filename); break; } } elseif (function_exists('getimagesizefromstring')) { $info = getimagesizefromstring($this->imagestring); } else { throw new Exception('PHP 5.4 is required to use method getimagesizefromstring'); } $this->original_info = array( 'width' => $info[0], 'height' => $info[1], 'orientation' => $this->get_orientation(), 'exif' => function_exists('exif_read_data') && $info['mime'] === 'image/jpeg' && $this->imagestring === null ? $this->exif = @exif_read_data($this->filename) : null, 'format' => preg_replace('/^image\//', '', $info['mime']), 'mime' => $info['mime'] ); $this->width = $info[0]; $this->height = $info[1]; imagesavealpha($this->image, true); imagealphablending($this->image, true); return $this; } /** * Same as PHP's imagecopymerge() function, except preserves alpha-transparency in 24-bit PNGs * * @param $dst_im * @param $src_im * @param $dst_x * @param $dst_y * @param $src_x * @param $src_y * @param $src_w * @param $src_h * @param $pct * * @link http://www.php.net/manual/en/function.imagecopymerge.php#88456 * */ protected function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct) { // Get image width and height and percentage $pct /= 100; $w = imagesx($src_im); $h = imagesy($src_im); // Turn alpha blending off imagealphablending($src_im, false); // Find the most opaque pixel in the image (the one with the smallest alpha value) $minalpha = 127; for ($x = 0; $x < $w; $x++) { for ($y = 0; $y < $h; $y++) { $alpha = (imagecolorat($src_im, $x, $y) >> 24) & 0xFF; if ($alpha < $minalpha) { $minalpha = $alpha; } } } // Loop through image pixels and modify alpha for each for ($x = 0; $x < $w; $x++) { for ($y = 0; $y < $h; $y++) { // Get current alpha value (represents the TANSPARENCY!) $colorxy = imagecolorat($src_im, $x, $y); $alpha = ($colorxy >> 24) & 0xFF; // Calculate new alpha if ($minalpha !== 127) { $alpha = 127 + 127 * $pct * ($alpha - 127) / (127 - $minalpha); } else { $alpha += 127 * $pct; } // Get the color index with new alpha $alphacolorxy = imagecolorallocatealpha($src_im, ($colorxy >> 16) & 0xFF, ($colorxy >> 8) & 0xFF, $colorxy & 0xFF, $alpha); // Set pixel with the new color + opacity if (!imagesetpixel($src_im, $x, $y, $alphacolorxy)) { return; } } } // Copy it imagesavealpha($dst_im, true); imagealphablending($dst_im, true); imagesavealpha($src_im, true); imagealphablending($src_im, true); imagecopy($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h); } /** * Same as imagettftext(), but allows for a stroke color and size * * @param object &$image A GD image object * @param float $size The font size * @param float $angle The angle in degrees * @param int $x X-coordinate of the starting position * @param int $y Y-coordinate of the starting position * @param int &$textcolor The color index of the text * @param int &$stroke_color The color index of the stroke * @param int $stroke_size The stroke size in pixels * @param string $fontfile The path to the font to use * @param string $text The text to output * * @return array This method has the same return values as imagettftext() * */ protected function imagettfstroketext(&$image, $size, $angle, $x, $y, &$textcolor, &$strokecolor, $stroke_size, $fontfile, $text) { for( $c1 = ($x - abs($stroke_size)); $c1 <= ($x + abs($stroke_size)); $c1++ ) { for($c2 = ($y - abs($stroke_size)); $c2 <= ($y + abs($stroke_size)); $c2++) { $bg = imagettftext($image, $size, $angle, $c1, $c2, $strokecolor, $fontfile, $text); } } return imagettftext($image, $size, $angle, $x, $y, $textcolor, $fontfile, $text); } /** * Ensures $value is always within $min and $max range. * * If lower, $min is returned. If higher, $max is returned. * * @param int|float $value * @param int|float $min * @param int|float $max * * @return int|float * */ protected function keep_within($value, $min, $max) { if ($value < $min) { return $min; } if ($value > $max) { return $max; } return $value; } /** * Converts a hex color value to its RGB equivalent * * @param string $color Hex color string, array(red, green, blue) or array(red, green, blue, alpha). * Where red, green, blue - integers 0-255, alpha - integer 0-127 * * @return array|bool * */ protected function normalize_color($color) { if (is_string($color)) { $color = trim($color, '#'); if (strlen($color) == 6) { list($r, $g, $b) = array( $color[0].$color[1], $color[2].$color[3], $color[4].$color[5] ); } elseif (strlen($color) == 3) { list($r, $g, $b) = array( $color[0].$color[0], $color[1].$color[1], $color[2].$color[2] ); } else { return false; } return array( 'r' => hexdec($r), 'g' => hexdec($g), 'b' => hexdec($b), 'a' => 0 ); } elseif (is_array($color) && (count($color) == 3 || count($color) == 4)) { if (isset($color['r'], $color['g'], $color['b'])) { return array( 'r' => $this->keep_within($color['r'], 0, 255), 'g' => $this->keep_within($color['g'], 0, 255), 'b' => $this->keep_within($color['b'], 0, 255), 'a' => $this->keep_within(isset($color['a']) ? $color['a'] : 0, 0, 127) ); } elseif (isset($color[0], $color[1], $color[2])) { return array( 'r' => $this->keep_within($color[0], 0, 255), 'g' => $this->keep_within($color[1], 0, 255), 'b' => $this->keep_within($color[2], 0, 255), 'a' => $this->keep_within(isset($color[3]) ? $color[3] : 0, 0, 127) ); } } return false; } }
/
Имя
Дата
Размер
..
2026-10-02
.well-known
2022-05-24
0419be9f6cf559b70d22f61f9fc82f38
2013-06-02
FirmClasses
2015-12-22
PHPMailer
2014-06-23
adadurov
2013-04-27
admin
2026-10-02
afisha
2023-12-27
ajax
2018-07-13
api
2018-01-23
app
2026-10-01
auth
2016-12-20
banner
2020-08-31
bootstrap
2019-02-07
busines
2020-01-15
captcha
2013-04-27
chat
2013-04-27
cron
2026-10-02
css
2019-12-13
error
2013-04-27
feedback
2017-01-27
filechange
2017-06-02
firma
2020-04-06
fonts
2020-04-06
forum
2026-10-01
fotogal
2019-04-15
friends
2017-02-13
fstat
2026-10-02
horoscop
2016-02-15
iframe_banners
2023-11-01
images
2023-12-26
img
2024-09-23
imgprivat
2013-04-27
inc
2026-10-01
job
2023-12-21
js
2019-02-14
kcaptcha
2015-12-30
klient
2018-10-18
konkurs
2016-04-14
konsult
2016-02-15
less
2015-09-25
lib
2013-04-27
library
2010-05-05
life
2024-01-25
maps
2017-11-10
news
2024-04-27
oblast
2017-02-02
partners
2018-05-08
photo_loop
2016-03-01
php_sess
2016-12-23
plugins
2016-02-17
pogoda
2026-10-02
politics
2026-05-25
private
2026-10-01
public
2013-04-27
realty
2017-03-15
realty2
2016-04-11
realty_old
2016-05-05
restoran
2017-07-13
saplnk
2018-10-15
scripts
2013-04-27
search
2019-03-04
sitemaps
2024-09-20
stat
2016-03-01
task
2017-02-14
temp
2015-04-04
template
2016-11-18
tests
2020-02-11
user
2017-08-17
user_file
2020-03-10
user_foto
2026-10-02
vendor
2020-02-07
vendor_old
2020-02-11
viktorina
2017-03-21
visitka
2020-02-26
widgets
2016-11-18
.ftpaccess
2025-04-01
322 байт
.ftpaccess~
2024-10-07
323 байт
.htaccess
2026-05-25
2 кб.
.htaccess~
2024-03-21
2 кб.
403.html
2011-08-08
532 байт
404.php
2017-02-16
42 байт
Class.firma.php
2015-12-22
2 кб.
SimpleImage.php
2016-02-18
43 кб.
_firma.php
2015-12-22
11 кб.
add_moder.php
2016-02-15
426 байт
ajax.php
2016-01-18
3 кб.
app.js
2016-11-23
2 кб.
autoloader.php
2026-10-02
8 кб.
autoloader.php.bak_hostallow
2020-02-04
8 кб.
autoloader_back.php
2019-04-02
7 кб.
autoloader_cli.php
2020-02-07
4 кб.
ban_site.php
2017-02-17
787 байт
banlist.php
2019-01-28
2 кб.
banner_klient.php
2017-03-20
14 кб.
banner_right.inc
2010-05-03
101 байт
bridge.swf
2014-10-17
308 байт
change_password_all.php
2022-04-11
1 кб.
change_password_all.php~
2020-03-05
930 байт
check_iframe.php
2018-05-29
324 байт
check_test.html
2018-06-08
467 байт
class.upload.php
2015-11-02
267 кб.
click_b.php
2017-03-21
652 байт
click_banner.php
2017-02-14
365 байт
composer.json
2020-02-07
528 байт
composer.lock
2020-02-07
46 кб.
config.inc.php
2026-10-02
9 кб.
config.inc.php.bak.cutover
2026-10-01
9 кб.
config.inc.php.bak_mysql_host_20261001213242
2026-10-01
9 кб.
config.inc.php.bak_mysql_host_20261001213307
2026-10-01
9 кб.
config.inc.php.bak_prod_urls
2024-01-09
9 кб.
config.inc.php~
2022-03-03
9 кб.
config_lang.php
2016-11-18
195 байт
confirm.php
2016-12-23
503 байт
confirm_wait.php
2019-05-07
3 кб.
count.php
2017-03-01
6 кб.
custom_user_login.php
2021-09-08
362 байт
da4020760cc057069ee2048b32378410.flv
2016-03-23
19443 кб.
example.php
2016-03-21
32 кб.
favicon.ico
2006-05-11
1 кб.
fb.php
2015-12-14
2 кб.
fb_reg.php
2015-12-14
3 кб.
firm_indexator.php
2017-08-18
303 байт
firma.php
2024-08-23
5 кб.
firma.php~
2020-04-10
5 кб.
firma_back.php
2019-04-03
5 кб.
forma_firm.php
2026-05-25
11 кб.
forma_firm.php~
2023-11-10
11 кб.
forum_reindex.php
2017-09-12
245 байт
func.php
2026-10-02
286 кб.
func.php.bak.authorize_20261002
2026-10-02
286 кб.
func.php.bak.pagination_20261002
2026-10-02
286 кб.
func.php.bak.setnames_20261002
2022-03-03
286 кб.
func.php~
2021-03-15
286 кб.
func_new.php
2019-08-08
12 кб.
go_to_site.php
2017-03-24
674 байт
google3734f948a59c1f00.html
2017-10-10
53 байт
index.php
2026-01-14
13 кб.
index.php~
2024-03-14
12 кб.
index1.html
2015-09-25
70 кб.
index2.html
2023-11-14
62 кб.
index2.html~
2023-05-11
62 кб.
index_back.php
2023-11-14
14 кб.
index_back.php~
2023-09-13
14 кб.
index_old.php
2018-07-11
6 кб.
industry.php
2026-05-25
14 кб.
industry.php~
2021-01-14
15 кб.
industry_03.02.php
2017-02-07
2 кб.
ins_user.php
2015-12-18
15 кб.
katalog_firm.php
2023-12-22
3 кб.
katalog_firm.php~
2019-03-17
3 кб.
katalog_firm_new.php
2018-01-16
3 кб.
katalog_firm_old.php
2016-04-11
3 кб.
katalog_search.php
2016-01-21
9 кб.
katalog_tovar.php
2015-11-09
6 кб.
live-597cb0d9.txt
2018-05-15
22 байт
logout.php
2015-12-14
1 кб.
mailsock.php
2012-12-18
3 кб.
md5ttt.php
2017-03-07
56 байт
mechta.jpg
2020-09-04
121 кб.
modifier.length.php
2015-12-23
745 байт
modifier.length.php~
2026-07-24
745 байт
news.rss
2026-10-02
72 кб.
news.rss~
2026-09-12
97 кб.
oauth_user_confirm.php
2017-07-03
762 байт
odkl.php
2015-12-08
2 кб.
odkl_reg.php
2015-12-14
3 кб.
otrasl.php
2017-02-07
452 байт
out_password.php
2015-12-14
4 кб.
password.php
2015-12-15
3 кб.
phpunit.xml.dist
2020-02-11
386 байт
politics.php
2026-05-25
621 байт
products.php
2020-04-28
2 кб.
quote_test.php
2017-02-17
636 байт
realdb.php
2016-12-29
108 байт
register_finish.php
2017-07-05
3 кб.
registration.php
2026-05-25
5 кб.
registration.php~
2015-12-10
5 кб.
registrationfb.php
2015-12-14
4 кб.
registrationok.php
2015-12-14
4 кб.
registrationvk.php
2015-12-11
4 кб.
restoran_indexator.php
2017-08-01
997 байт
robots.txt
2026-10-02
2 кб.
robots.txt.bak_prod
2026-01-14
2 кб.
robots.txt.stand_noindex
2026-10-02
88 байт
robots.txt~
2024-10-21
2 кб.
schet.png
2017-03-01
686 байт
schetchik.inc
2019-04-18
441 байт
search.php
2019-04-01
40 кб.
search_back.php
2019-03-20
39 кб.
sitemap_generator.php
2024-10-21
34 кб.
sitemap_generator.php~
2024-01-25
34 кб.
smtpEmailValidation.php
2015-12-09
7 кб.
ta.php
2015-12-11
2 кб.
ta_reg.php
2015-12-14
3 кб.
test.php
2020-04-06
67 кб.
user_form.inc.php
2012-05-28
11 кб.
user_info.php
2017-09-04
1 кб.
view_b.php
2014-06-16
2 кб.
view_banner.php
2009-10-26
820 байт
vote_frame.php
2019-03-21
7 кб.
vote_frame_back.php
2017-08-17
7 кб.
watermark.php
2014-08-19
1015 байт
yandex_60dbd5831b8ec85b.html
2019-04-25
161 байт
yandex_60dbd5831b8ec85b.html~
2026-07-24
161 байт
yb.php
2016-03-09
2 кб.
yesno.php
2014-01-17
1 кб.
Политика конфиденциальности.docx
2024-08-30
25 кб.
Политика конфиденциальности.docx~
2024-02-15
20 кб.
Согласие_на_обработку_персональных_данных_с_помощью_сервиса_«Яндекс.docx
2025-04-01
18 кб.
Загрузить файлы
Файл 1
Файл 2
Файл 3