src/Operation/Operation.php
protected function makeCrop(ARef $aRef, ImageSettingInterface $imageSetting, CropSettingInterface $cropSetting, array $item_attrs = [])
    {
        $manual = false;

        if(array_key_exists('manual', $item_attrs))
        {
            $manual = (bool) $item_attrs['manual'];
        }

        $resizes_dir = $this->pathResolver->getResizeDir();

        if (!is_readable($resizes_dir))
        {
            throw new OperationException('Дирректория ресайзов недоступна для чтения!');
        }

        $crops_dir = $this->pathResolver->getCropDir();

        if (!is_writable($crops_dir))
        {
            throw new OperationException('Дирректория кропов недоступна для записи!');
        }

        $crop_x = 0;
        $crop_y = 0;

        if(array_key_exists('x', $item_attrs))
        {
            $crop_x = $item_attrs['x'];
        }

        if(array_key_exists('y', $item_attrs))
        {
            $crop_y = $item_attrs['y'];
        }

        //Ищем целевой ресайз
        $targetResizeSetting = $cropSetting->getTarget();
        $target_prefix = $this->getImagePrefix($imageSetting->getEntityName(), $aRef->getId(), $imageSetting->getName(), GenVariant::RESIZE, $targetResizeSetting->getName());
        $target_path = $resizes_dir.'/'.$target_prefix;

        $target_file_name = false;

        foreach (glob($target_path.'.*') as $file)
        {
            if(is_dir($file))
            {
                continue;
            }

            $target_mime = File::mimeType($file);

            if($this->isVectorImage($target_mime))
            {
                throw new OperationException('Попытка выполнить кроп векторного файла '.$file.'!');
            }

            $target_file_name = $file;

            break;
        }

        if(!$target_file_name)
        {
            throw new OperationException('Не найден файл цели для кропа по пути '.$target_path.'!');
        }

        $target_extension = File::extension($target_file_name);

        //Формирование пути к файлу кропа
        $crop_prefix = $this->getImagePrefix($imageSetting->getEntityName(), $aRef->getId(), $imageSetting->getName(), GenVariant::CROP, $cropSetting->getName());
        $crop_file_name = $crop_prefix.'.'.$target_extension;
        $crop_path = $crops_dir.'/'.$crop_file_name;

        //Выполнение кропа картинки
        $crop_width = $cropSetting->getWidth();
        $crop_height = $cropSetting->getHeight();
        $crop_color = $cropSetting->getColor();

        $target = ImageFacade::make($target_file_name);

        //Размеры цели
        $target_width = $target->getWidth();
        $target_height = $target->getHeight();

        //Сценарий №1, если кроп больше цели и не спозиционирован
        if($target_width < $crop_width and $target_height < $crop_height and $crop_x === 0 and $crop_y === 0 and !$manual)
        {
            ImageFacade::canvas($crop_width, $crop_height, $crop_color)->insert($target, 'center')->save($crop_path, 100);
        }
        else //Сценарий №2, если кроп спозиционирован или меньше цели
        {
            $crop_left = $crop_x;
            $target_left = 0;

            $crop_right = $crop_x + $crop_width;
            $target_right = $target_width;

            $crop_top = $crop_y;
            $target_top = 0;

            $crop_bottom = $crop_y + $crop_height;
            $target_bottom = $target_height;

            //Если не пересекаются:
            //(Нижний край рамки кропа выше верхнего края цели)
            //или (верхний край рамки кропа ниже нижнего края цели)
            //или (правый край рамки кропа левее левого края цели)
            //или (левый край рамки кропа правее правого края цели)
            if($crop_bottom <= $target_top
                or $crop_top >= $target_bottom
                or $crop_right <= $target_left
                or $crop_left >= $target_right)
            {
                //Пустая картинка цветом фона кропа
                ImageFacade::canvas($crop_width, $crop_height, $crop_color)->save($crop_path, 100);
            }
            else
            {
                //Находим прямоугольник пересечения и вырезаем его

                //Если кроп внутри цели
                if($crop_left >= $target_left and $crop_right <= $target_right and $crop_top >= $target_top and $crop_bottom <= $target_bottom)
                {
                    $target->crop($crop_width, $crop_height, $crop_x, $crop_y);
                    $target->save($crop_path, 100);
                }
                //Если цель внутри кропа
                elseif($target_left >= $crop_left and $target_right <= $crop_right and $target_top >= $crop_top and $target_bottom <= $crop_bottom)
                {
                    ImageFacade::canvas($crop_width, $crop_height, $crop_color)->insert($target, 'top-left', abs($crop_x), abs($crop_y))->save($crop_path, 100);
                }
                else //Тогда находим прямоугольник совпадения
                {
                    //Координаты совпадения по X
                    if($crop_left <= $target_left)
                    {
                        $target_crop_x = 0;
                        $crop_insert_x = -$crop_left;
                    }
                    else
                    {
                        $target_crop_x = $crop_left;
                        $crop_insert_x = 0;
                    }

                    if($crop_right >= $target_right)
                    {
                        $target_crop_width = $target_width;
                    }
                    else
                    {
                        $target_crop_width = $target_width - ($target_right - $crop_right);
                    }

                    $target_crop_width -= $target_crop_x;


                    //Координаты совпадения по Y
                    if($crop_top <= $target_top)
                    {
                        $target_crop_y = 0;
                        $crop_insert_y = -$crop_top;
                    }
                    else
                    {
                        $target_crop_y = $crop_top;
                        $crop_insert_y = 0;
                    }

                    if($crop_bottom >= $target_bottom)
                    {
                        $target_crop_height = $target_height;
                    }
                    else
                    {
                        $target_crop_height = $target_height - ($target_bottom - $crop_bottom);
                    }

                    $target_crop_height -= $target_crop_y;


                    $target->crop($target_crop_width, $target_crop_height, $target_crop_x, $target_crop_y);

                    ImageFacade::canvas($crop_width, $crop_height, $crop_color)->insert($target, 'top-left', $crop_insert_x, $crop_insert_y)->save($crop_path, 100);
                }
            }
        }

        chmod($crop_path, 0644);

        $item_attrs['link'] = $this->pathResolver->getCropPath().'/'.$crop_file_name;
        //-----------------------------------------------------

        $this->dbAgent->cropToDb($aRef, $imageSetting, $cropSetting, $item_attrs);
    }
protected function makeCrop(ARef $aRef, ImageSettingInterface $imageSetting, CropSettingInterface $cropSetting, array $item_attrs = [])
    {
        $manual = false;

        if(array_key_exists('manual', $item_attrs))
        {
            $manual = (bool) $item_attrs['manual'];
        }

        $resizes_dir = $this->pathResolver->getResizeDir();

        if (!is_readable($resizes_dir))
        {
            throw new OperationException('Дирректория ресайзов недоступна для чтения!');
        }

        $crops_dir = $this->pathResolver->getCropDir();

        if (!is_writable($crops_dir))
        {
            throw new OperationException('Дирректория кропов недоступна для записи!');
        }

        $crop_x = 0;
        $crop_y = 0;

        if(array_key_exists('x', $item_attrs))
        {
            $crop_x = $item_attrs['x'];
        }

        if(array_key_exists('y', $item_attrs))
        {
            $crop_y = $item_attrs['y'];
        }

        //Ищем целевой ресайз
        $targetResizeSetting = $cropSetting->getTarget();
        $target_prefix = $this->getImagePrefix($imageSetting->getEntityName(), $aRef->getId(), $imageSetting->getName(), GenVariant::RESIZE, $targetResizeSetting->getName());
        $target_path = $resizes_dir.'/'.$target_prefix;

        $target_file_name = false;

        foreach (glob($target_path.'.*') as $file)
        {
            if(is_dir($file))
            {
                continue;
            }

            $target_mime = File::mimeType($file);

            if($this->isVectorImage($target_mime))
            {
                throw new OperationException('Попытка выполнить кроп векторного файла '.$file.'!');
            }

            $target_file_name = $file;

            break;
        }

        if(!$target_file_name)
        {
            throw new OperationException('Не найден файл цели для кропа по пути '.$target_path.'!');
        }

        $target_extension = File::extension($target_file_name);

        //Формирование пути к файлу кропа
        $crop_prefix = $this->getImagePrefix($imageSetting->getEntityName(), $aRef->getId(), $imageSetting->getName(), GenVariant::CROP, $cropSetting->getName());
        $crop_file_name = $crop_prefix.'.'.$target_extension;
        $crop_path = $crops_dir.'/'.$crop_file_name;

        //Выполнение кропа картинки
        $crop_width = $cropSetting->getWidth();
        $crop_height = $cropSetting->getHeight();
        $crop_color = $cropSetting->getColor();

        $target = ImageFacade::make($target_file_name);

        //Размеры цели
        $target_width = $target->getWidth();
        $target_height = $target->getHeight();

        //Сценарий №1, если кроп больше цели и не спозиционирован
        if($target_width < $crop_width and $target_height < $crop_height and $crop_x === 0 and $crop_y === 0 and !$manual)
        {
            ImageFacade::canvas($crop_width, $crop_height, $crop_color)->insert($target, 'center')->save($crop_path, 100);
        }
        else //Сценарий №2, если кроп спозиционирован или меньше цели
        {
            $crop_left = $crop_x;
            $target_left = 0;

            $crop_right = $crop_x + $crop_width;
            $target_right = $target_width;

            $crop_top = $crop_y;
            $target_top = 0;

            $crop_bottom = $crop_y + $crop_height;
            $target_bottom = $target_height;

            //Если не пересекаются:
            //(Нижний край рамки кропа выше верхнего края цели)
            //или (верхний край рамки кропа ниже нижнего края цели)
            //или (правый край рамки кропа левее левого края цели)
            //или (левый край рамки кропа правее правого края цели)
            if($crop_bottom <= $target_top
                or $crop_top >= $target_bottom
                or $crop_right <= $target_left
                or $crop_left >= $target_right)
            {
                //Пустая картинка цветом фона кропа
                ImageFacade::canvas($crop_width, $crop_height, $crop_color)->save($crop_path, 100);
            }
            else
            {
                //Находим прямоугольник пересечения и вырезаем его

                //Если кроп внутри цели
                if($crop_left >= $target_left and $crop_right <= $target_right and $crop_top >= $target_top and $crop_bottom <= $target_bottom)
                {
                    $target->crop($crop_width, $crop_height, $crop_x, $crop_y);
                    $target->save($crop_path, 100);
                }
                //Если цель внутри кропа
                elseif($target_left >= $crop_left and $target_right <= $crop_right and $target_top >= $crop_top and $target_bottom <= $crop_bottom)
                {
                    ImageFacade::canvas($crop_width, $crop_height, $crop_color)->insert($target, 'top-left', abs($crop_x), abs($crop_y))->save($crop_path, 100);
                }
                else //Тогда находим прямоугольник совпадения
                {
                    //Координаты совпадения по X
                    if($crop_left <= $target_left)
                    {
                        $target_crop_x = 0;
                        $crop_insert_x = -$crop_left;
                    }
                    else
                    {
                        $target_crop_x = $crop_left;
                        $crop_insert_x = 0;
                    }

                    if($crop_right >= $target_right)
                    {
                        $target_crop_width = $target_width;
                    }
                    else
                    {
                        $target_crop_width = $target_width - ($target_right - $crop_right);
                    }

                    $target_crop_width -= $target_crop_x;


                    //Координаты совпадения по Y
                    if($crop_top <= $target_top)
                    {
                        $target_crop_y = 0;
                        $crop_insert_y = -$crop_top;
                    }
                    else
                    {
                        $target_crop_y = $crop_top;
                        $crop_insert_y = 0;
                    }

                    if($crop_bottom >= $target_bottom)
                    {
                        $target_crop_height = $target_height;
                    }
                    else
                    {
                        $target_crop_height = $target_height - ($target_bottom - $crop_bottom);
                    }

                    $target_crop_height -= $target_crop_y;


                    $target->crop($target_crop_width, $target_crop_height, $target_crop_x, $target_crop_y);

                    ImageFacade::canvas($crop_width, $crop_height, $crop_color)->insert($target, 'top-left', $crop_insert_x, $crop_insert_y)->save($crop_path, 100);
                }
            }
        }

        chmod($crop_path, 0644);

        $item_attrs['link'] = $this->pathResolver->getCropPath().'/'.$crop_file_name;
        //-----------------------------------------------------

        $this->dbAgent->cropToDb($aRef, $imageSetting, $cropSetting, $item_attrs);
    }
@param \Interpro\Core\Contracts\Ref\ARef $aRef
@param \Interpro\ImageAggr\Contracts\Settings\ImageSetting $imageSetting
@param \Interpro\ImageAggr\Contracts\Settings\CropSetting $cropSetting
@param array $item_attrs

@return void