<?
//namespace App;

class AcResizeImage
{
    private $image;
    private $width;
    private $height;
    private $type;

    /**
     * Инициализация объекта
     * @param $file string	Путь к временному файлу
     */
    function __construct($file)
    {
        if (@!file_exists($file)) return $file; //exit("File does not exist");
        if(!$this->setType($file)) return $file; //exit("File is not an image");
        $this->openImage($file);
        $this->setSize();
    }

    /**
     * Изменение размеров изображения
     *
     * Оба принимаемых параметра необязательны.
     * Если переданы и ширина и высота, изображение ужмётся в рамки.
     * Если передана лишь ширина - изображение сжимается по ней (аналогично и с высотой)
     *
     * @param $width integer		Новая ширина изображения
     * @param $height integer	Новая высота изображения
     * @return object 			Текущий объект класса
     */
    public function resize($width = false, $height = false)
    {
        /**
         * В зависимости от типа ресайза, запишем в $newSize новые размеры изображения.
         */
        if(is_numeric($width) && is_numeric($height) && $width > 0 && $height > 0)
        {
            $newSize = $this->getSizeByFramework($width, $height);
        }
        else if(is_numeric($width) && $width > 0)
        {
            $newSize = $this->getSizeByWidth($width);
        }
        else if(is_numeric($height) && $height > 0)
        {
            $newSize = $this->getSizeByHeight($height);
        }
        else $newSize = array($this->width, $this->height);
        $newImage = imagecreatetruecolor($newSize[0], $newSize[1]);
        //завернуть в отдельную функцию, сжимающую изображение поэтапно

       if ($this->type == 'png') {
           $src=imagecreatefrompng($this->file);
           imagealphablending($newImage, false);
           imagesavealpha($newImage,true);
           $transparent = imagecolorallocatealpha($newImage, 255, 255, 255, 127);
           imagefilledrectangle($newImage, 0, 0,$newSize[0], $newSize[1], $transparent);
           imagecopyresampled($newImage, $src, 0, 0, 0, 0, $newSize[0], $newSize[1], $this->width, $this->height);
       } else {
           imagecopyresampled($newImage, $this->image, 0, 0, 0, 0, $newSize[0], $newSize[1], $this->width, $this->height);
       }

        $this->image = $newImage;
        $this->setSize();
        return $this;
    }

    /**
     * Функция для обрезки изображения.
     * Функция cropSave сохраняет обрезанное изображение и возвращает текущий объект класса acResizeImage.
     *
     * @param $x0 integer	Координата x точки начала обрезки
     * @param $y0 integer	Координата y точки начала обрезки
     * @param $w integer		Ширина вырезаемой области
     * @param $h integer		Высота вырезаемой области
     * @return object		Текущий объект класса
     */
    public function crop($x0 = 0, $y0 = 0, $w = false, $h = false)
    {
        if(!is_numeric($x0) || $x0 < 0 || $x0 >= $this->width) $x0 = 0;
        if(!is_numeric($y0) || $y0 < 0 || $y0 >= $this->height) $y0 = 0;
        if(!is_numeric($w) || $w <= 0 || $w > $this->width - $x0) $w = $this->width - $x0;
        if(!is_numeric($h) || $h <= 0 || $h > $this->height - $y0) $h = $this->height - $y0;
        return $this->cropSave($x0, $y0, $w, $h);
    }

    /**
     * Функция, вырезающая квадратную область из исходного изображения
     * Функция cropSave сохраняет обрезанное изображение и возвращает текущий объект класса acResizeImage.
     * Все параметры необязательны.
     * Если не было ничего передано, будет вырезана центральная максимальная квадратная область.
     *
     * @param $x0 integer		Координата x точки начала обрезки (по умолчанию - false)
     * @param $y0 integer		Координата y точки начала обрезки (по умолчанию - false)
     * @param $size integer		Сторона вырезаемой квадратной области
     * @return object 			Текущий объект класса
     */
    public  function cropSquare($x0 = false, $y0 = false, $size = false)
    {
        if(!is_numeric($size) || $size <= 0) $size = false;
        if(!is_numeric($x0) && !is_numeric($y0))
        {
            if($this->width < $this->height)
            {
                $x0 = 0;
                if(!$size || $size > $this->width)
                {
                    $size = $this->width;
                    $y0 = round(($this->height - $size) / 2);
                }
                else $y0 = 0;
            }
            else
            {
                $y0 = 0;
                if(!$size || $size > $this->height)
                {
                    $size = $this->height;
                    $x0 = round(($this->width - $size) / 2);
                }
                else $x0 = 0;
            }
        }
        else
        {
            if(!is_numeric($x0) || $x0 <= 0 || $x0 >= $this->width) $x0 = 0;
            if(!is_numeric($y0) || $y0 <= 0 || $y0 >= $this->height) $y0 = 0;
            if(!$size || $this->width < $size + $x0) $size = $this->width - $x0;
            if(!$size || $this->height < $size + $y0) $size = $this->height - $y0;
        }
        return $this->cropSave($x0, $y0, $size, $size);
    }

    /**
     * Приватная функция, сохраняющая обрезанное изображение.
     *
     * @return object	Текущий объект класса
     */
    private function cropSave($x0, $y0, $w, $h)
    {
        $newImage = imagecreatetruecolor($w, $h);
        imagecopyresampled($newImage, $this->image, 0, 0, $x0, $y0, $w, $h, $w, $h);
        $this->image = $newImage;
        $this->setSize();
        return $this;
    }

    /**
     * Функция для создания миниатюр изображений.
     * Функция getSizeByThumbnail возвращает новые размеры изображения.
     *
     * @param $width integer		Ширина миниатюры
     * @param $height integer	Высота миниатюры
     * @param $c integer			Коэффициент превышения...
     * @return object			Текущий объект класса
     */
    public function thumbnail($width, $height, $c = 2)
    {
        if(!is_numeric($width) || $width <= 0) $width = $this->width;
        if(!is_numeric($height) || $height <= 0) $height = $this->height;
        if(!is_numeric($c) || $c <= 1) $c = 2;
        $newSize = $this->getSizeByThumbnail($width, $height, $c);

        $newImage = imagecreatetruecolor($newSize[0], $newSize[1]);

        if ($this->type == 'png') {
            $src=imagecreatefrompng($this->file);
            imagealphablending($newImage, false);
            imagesavealpha($newImage,true);
            $transparent = imagecolorallocatealpha($newImage, 255, 255, 255, 127);
            imagefilledrectangle($newImage, 0, 0,$newSize[0], $newSize[1], $transparent);
            imagecopyresampled($newImage, $src, 0, 0, 0, 0, $newSize[0], $newSize[1], $this->width, $this->height);
        } else {
            imagecopyresampled($newImage, $this->image, 0, 0, 0, 0, $newSize[0], $newSize[1], $this->width, $this->height);
        }

        $this->image = $newImage;
        $this->setSize();
        return $this;
    }

    /**
     * Функция, сохраняющая изображение в файл
     *
     * @param $path string		Путь, по которому следует сохранить файл
     * @param $fileName string	Имя нового файла
     * @param $type string		Тип файла (по умолчанию (false) - тот же, что и у исходного изображения)
     * @param $rewrite boolean	Флаг, определяющий, можно ли перезаписывать файлы с одинаковыми именами
     * @param $quality integer	Качество изображения для JPG-файлов
     * @return string			Адрес нового файла
     */
    public function save($path = '', $fileName, $type = false, $rewrite = false, $quality = 100)
    {
        if(trim($fileName) == '' || $this->image === false) return false;
        $type = strtolower($type);
        switch($type)
        {
            case false:
                $savePath = $path.trim($fileName).".".$this->type;
                switch($this->type)
                {
                    case 'jpg':
                        if(!$rewrite && @file_exists($savePath)) return false;
                        if(!is_numeric($quality) || $quality < 0 || $quality > 100) $quality = 100;
                        imagejpeg($this->image, $savePath, $quality);
                        return $savePath;
                    case 'png':
                        if(!$rewrite && @file_exists($savePath)) return false;
                        imagepng($this->image, $savePath);
                        return $savePath;
                    case 'gif':
                        if(!$rewrite && @file_exists($savePath)) return false;
                        imagegif($this->image, $savePath);
                        return $savePath;
                    default:
                        return false;
                }
                break;
            case 'jpg':
                $savePath = $path.trim($fileName).".".$type;
                if(!$rewrite && @file_exists($savePath)) return false;
                if(!is_numeric($quality) || $quality < 0 || $quality > 100) $quality = 100;
                imagejpeg($this->image, $savePath, $quality);
                return $savePath;
            case 'png':
                $savePath = $path.trim($fileName).".".$type;
                if(!$rewrite && @file_exists($savePath)) return false;
                imagepng($this->image, $savePath);
                return $savePath;
            case 'gif':
                $savePath = $path.trim($fileName).".".$type;
                if(!$rewrite && @file_exists($savePath)) return false;
                imagegif($this->image, $savePath);
                return $savePath;
            default:
                return false;
        }
    }

    /**
     * Приватная функция, "открывающая" файл в зависимости от типа изображения.
     *
     * @param $file string	Путь исходного файла
     */
    private function openImage($file)
    {
        switch($this->type)
        {
            case 'jpg':
                $this->image = imagecreatefromjpeg($file);
                break;
            case 'png':
                $this->image = imagecreatefrompng($file);

                break;
            case 'gif':
                $this->image = @imagecreatefromgif($file);
                break;
            default:
                exit("File is not an image");
        }
        $this->file = $file;
    }

    /**
     * Приватная функция, записывающая в поле type тип исходного изображения
     *
     * @param $file string	Путь исходного файла
     * @return boolean		TRUE, если файл является изображением. FALSE - в противном случае.
     */
    private function setType($file)
    {
        $mime = mime_content_type($file);
        switch($mime)
        {
            case 'image/jpeg':
                $this->type = "jpg";
                return true;
            case 'image/png':
                $this->type = "png";
                return true;
            case 'image/gif':
                $this->type = "gif";
                return true;
            default:
                return false;
        }
    }

    /**
     * Приватная функция, записывающая размеры исходного изображения
     */
    private function setSize()
    {
        $this->width = imagesx($this->image);
        $this->height = imagesy($this->image);
    }

    /**
     * Приватная функция, определяющая размеры нового изображения при вписывании его в рамки.
     * Сжатие происходит пропорционально.
     *
     * @param $width integer		Максимальная ширина нового изображения
     * @param $height integer	Максимальная высота нового изображения
     * @return array 			Массив, содержащий размеры нового изображения
     */
    private function getSizeByFramework($width, $height)
    {
        if($this->width <= $width && $this->height <= $height)
            return array($this->width, $this->height);
        if($this->width / $width > $this->height / $height)
        {
            $newSize[0] = $width;
            $newSize[1] = round($this->height * $width / $this->width);
        }
        else
        {
            $newSize[1] = $height;
            $newSize[0] = round($this->width * $height / $this->height);
        }
        return $newSize;
    }

    /**
     * Приватная функция, определяющая размеры нового изображения при сжатии по ширине.
     * Сжатие происходит пропорционально.
     *
     * @param $width integer		Максимальная ширина нового изображения
     * @return array 			Массив, содержащий размеры нового изображения
     */
    private function getSizeByWidth($width)
    {
        if($width >= $this->width) return array($this->width, $this->height);
        $newSize[0] = $width;
        $newSize[1] = round($this->height * $width / $this->width);
        return $newSize;
    }

    /**
     * Приватная функция, определяющая размеры нового изображения при сжатии по высоте.
     * Сжатие происходит пропорционально.
     *
     * @param $height integer	Максимальная высота нового изображения
     * @return array 			Массив, содержащий размеры нового изображения
     */
    private function getSizeByHeight($height)
    {
        if($height >= $this->height) return array($this->width, $this->height);
        $newSize[1] = $height;
        $newSize[0] = round($this->width * $height / $this->height);
        return $newSize;
    }

    /**
     * Приватная функция, определяющая размеры нового изображения при создании миниатюры.
     * Функция вписывает изображение в указанную область, стараясь максимально заполнить её.
     * Если после ужатия по одной из сторон, вторая сторона привышает размеры области более чем в $c раз,
     * то ужатие происходит по второй стороне.
     * Если же вторая сторона превышает размер области в 2 * $c раз, то стороны уменьшаются в 2 раза.
     * Если одна из сторон заведомо меньше соответствующей стороны области,
     * проверяется, не превышает ли другая сторона соответствующую сторону области в $c раз и 2 * $c.
     * Если ресайз производится не по ширине, а по высоте, переменные, содержащие размеры исходного изображения
     * и размеры миниатюры, меняются местами.
     * Также местами меняются мирина и высота в возвращаемом массиве.
     *
     * @param $width integer		Максимальная ширина нового изображения
     * @param $height integer	Максимальная высота нового изображения
     * @param $с integer			Коэффициент превышения...
     * @return array 			Массив, содержащий размеры нового изображения
     */
    private function getSizeByThumbnail($width, $height, $c)
    {
        if($this->width <= $width && $this->height <= $height)
            return array($this->width, $this->height);
        $realW = $this->width;
        $realH = $this->height;

        $rotate = false;
        if($width / $realW <= $height / $realH)
        {
            $t = $realH;
            $realH = $realW;
            $realW = $t;
            $t = $width;
            $width = $height;
            $height = $t;
            $rotate = true;
        }

        $limX = $c * $width;
        $limY = $c * $height;
        $possH = $realH * $width / $realW;

        if($realW > $width)
        {
            if($possH <= $limY)
            {
                $newSize[0] = $width;
                $newSize[1] = round($possH);
            }
            else
            {
                if($possH <= 2 * $limY)
                {
                    $newSize[1] = $limY;
                    $newSize[0] = $realW * $newSize[1] / $realH;
                }
                else
                {
                    $newSize[0] = $width / 2;
                    $newSize[1] = $realH * $newSize[0] / $realW;
                }
            }
        }
        else
        {
            if($realH <= $limY)
            {
                $newSize[0] = $realW;
                $newSize[1] = $realH;
            }
            else
            {
                if($realH <= 2 * $limY)
                {
                    if($realW * $limY / $realH >= $width / 2)
                    {
                        $newSize[1] = $limY;
                        $newSize[0] = $realW * $limY / $realH;
                    }
                    else
                    {
                        $newSize[0] = $width / 2;
                        $newSize[1] = $realH * $newSize[0] / $realW;
                    }
                }
                else
                {
                    $newSize[0] = $width / 2;
                    $newSize[1] = $realH * $newSize[0] / $realW;
                }
            }
        }
        if($rotate)
        {
            $t = $newSize[0];
            $newSize[0] = $newSize[1];
            $newSize[1] = $t;
        }
         return $newSize;
    }
}<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="https://kovcheg-developer.com.ua/wp-sitemap-index.xsl" ?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><sitemap><loc>https://kovcheg-developer.com.ua/wp-sitemap-posts-post-1.xml</loc></sitemap><sitemap><loc>https://kovcheg-developer.com.ua/wp-sitemap-posts-page-1.xml</loc></sitemap><sitemap><loc>https://kovcheg-developer.com.ua/wp-sitemap-taxonomies-category-1.xml</loc></sitemap><sitemap><loc>https://kovcheg-developer.com.ua/wp-sitemap-users-1.xml</loc></sitemap></sitemapindex>
