Rotate an image and save it.
If no angle to rotate is passed then we attempt to read it from exif data.

@param string $path The path of the image to work with, and overwrite
@param int $rotate A specific rotation angle to apply (clockwise)

@return void
518257
public static function rotate($path, $rotate = null)
    {
        if ($rotate === null) {
            $exif = exif_read_data($path);
            switch ($exif["Orientation"]) {
                case 3:
                    $rotate = 180;
                    break;
                case 6:
                    $rotate = 90;
                    break;
                case 8:
                    $rotate = -90;
                    break;
            }
        }
        if (!$rotate) {
            return;
        }

        $format = getimagesize($path)[2];

        $image = static::create($path, $format);

        $rotate = imagerotate($image, $rotate * -1, 0);

        static::save($rotate, $path, $format);
    }
717969
public function mapAssetLocation($path)
    {
        $url = URL::to('/' . ltrim($path, '/'))->getRelativeUrl();
        $this->setAssetURL($url);
    }
352756
public function next($offset = 1)
    {
        $offset = (null === $offset) ? 1 : $offset % $this->count();
        $this->rotation = \array_merge(
            \array_slice(
                $this->rotation,
                $offset
            ),
            \array_slice(
                $this->rotation,
                0,
                $offset
            )
        );
    }
111970
public function setPath($path)
	{
		if (!is_file($path)) {
			throw new \InvalidArgumentException('Path '.$path.' invalid');
		}
		$this->path = realpath($path);
	}
16927
private static function rmdirRecursive($path)
    {
        $files = scandir($path);
        array_shift($files);
        array_shift($files);

        foreach ($files as $file) {
            $file = $path.DIRECTORY_SEPARATOR.$file;
            if (is_dir($file)) {
                self::rmdirRecursive($file);
            } else {
                unlink($file);
            }
        }

        rmdir($path);
    }
485123
public function do_rotate($degrees, $background = 0xffffff, $alpha = 1.0)
    {
        $transparent = imagecolorallocatealpha($this->_image, ($background >> 16) & 0xFF, ($background >> 8) & 0xFF,
            $background & 0xFF, $alpha * 127);
        $image = imagerotate($this->_image, 360 - $degrees, $transparent, true);
        imagealphablending($image, false);
        imagesavealpha($image, true);

        imagedestroy($this->_image);
        $this->_image = $image;
        $this->_width = imagesx($image);
        $this->_height = imagesy($image);

        return $this;
    }
504319
public function delete($path=null)
	{
		if (is_null($path)) return;

		$basePath = $this->getImageBasePath();
		$imagePath = $basePath.'/'.$path;

		if (File::exists($imagePath)) {
			File::delete($imagePath);
		}
	}
1163610
public function rotate(&$image, $angle, $color = null)
    {

        if ($image->isAnimated()) { // Ignore animated GIF for now
            return $this;
        }

        $color = ($color !== null) ? $color : new Color('#000000');
        list($r, $g, $b, $alpha) = $color->getRgba();

        $image->getCore()->rotateImage(new \ImagickPixel("rgba($r, $g, $b, $alpha)"), $angle * -1);

        return $this;
    }
929899
protected function copyBrokenImage($path)
    {
        try {
            $thumbnailDir = dirname($path);
            if (!File::isDirectory($thumbnailDir) && File::makeDirectory($thumbnailDir, 0777, true) === false) {
                return;
            }

            File::copy($this->getBrokenImagePath(), $path);
        }
        catch (Exception $ex) {
            traceLog($ex->getMessage());
        }
    }
426419
public function rotate($angle = 90, $background = '#fff', $ignore = 0) {
		$this->image = imagerotate($this->image, $angle, $this->getColorWithRGB($background), $ignore);
		return $this->image !== false;
	}
498554
public function rotateExif()
    {
        if (!in_array($this->fileType, array(IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM))) {
            $this->log("Autorotate ignored, EXIF not supported by this filetype.");
            return $this;
        }

        $exif = exif_read_data($this->pathToImage);

        if (!empty($exif['Orientation'])) {
            switch ($exif['Orientation']) {
                case 3:
                    $this->log("Autorotate 180.");
                    $this->rotate(180, $this->bgColor);
                    break;

                case 6:
                    $this->log("Autorotate -90.");
                    $this->rotate(-90, $this->bgColor);
                    break;

                case 8:
                    $this->log("Autorotate 90.");
                    $this->rotate(90, $this->bgColor);
                    break;

                default:
                    $this->log("Autorotate ignored, unknown value as orientation.");
            }
        } else {
            $this->log("Autorotate ignored, no orientation in EXIF.");
        }

        return $this;
    }
498336
public function setPath(string $path)
    {
        $this->path = $path;
        
        // update path to templates and preload list of templates.
        $this->contentPath = $this->path . DIR_CONTENT_BASENAME;
        $this->templatesPath = $this->contentPath . DIR_TEMPLATES_BASENAME;
        
        $this->templates = File::listFilesRecursively($this->templatesPath, false, EXT_PART, EXT_PAGE);
    }
5449
public function setRotationAngle($rotationAngle) {
        $this->rotationAngle = (int)$rotationAngle;
        if ($this->rotationAngle !== 90 && $this->rotationAngle !== 180 && $this->rotationAngle !== 270) {
            $this->rotationAngle = 0;
        }

        $this->rotationAngle = (360 - $this->rotationAngle) % 360;
    }
325424
private function autoRotate(string $path): self
    {
        $exifData = exif_read_data($path);
        if (false !== $exifData && true === array_key_exists('Orientation', $exifData)) {
            $imageData = null;
            switch ($exifData['Orientation']) {
                case self::ORIENTATION_UPSIDE_DOWN:
                    $imageData = imagerotate($this->workingData, 180, 0);
                    break;
                case self::ORIENTATION_ROTATE_COUNTER_CLOCKWISE:
                    $imageData = imagerotate($this->workingData, -90, 0);
                    break;
                case self::ORIENTATION_ROTATE_CLOCKWISE:
                    $imageData = imagerotate($this->workingData, 90, 0);
                    break;
            }
            if (null !== $imageData) {
                $this->workingData = $imageData;
            }
        }
        return $this;
    }
227390
public function setPath(string $path)
    {
        $info = pathinfo($path);

        $this->setLocation($info["dirname"] ?? "");
        $this->setName($info["filename"] ?? "");
    }
647854
protected function _autorotate(\Imagick $image)
    {
        switch ($image->getImageOrientation()) {
            case \Imagick::ORIENTATION_TOPRIGHT:
                $image->flopImage();
                break;
            case \Imagick::ORIENTATION_BOTTOMRIGHT:
                $image->rotateImage('#000', 180);
                break;
            case \Imagick::ORIENTATION_BOTTOMLEFT:
                $image->flopImage();
                $image->rotateImage('#000', 180);
                break;
            case \Imagick::ORIENTATION_LEFTTOP:
                $image->flopImage();
                $image->rotateImage('#000', -90);
                break;
            case \Imagick::ORIENTATION_RIGHTTOP:
                $image->rotateImage('#000', 90);
                break;
            case \Imagick::ORIENTATION_RIGHTBOTTOM:
                $image->flopImage();
                $image->rotateImage('#000', 90);
                break;
            case \Imagick::ORIENTATION_LEFTBOTTOM:
                $image->rotateImage('#000', -90);
                break;
        }
        $image->setImageOrientation(\Imagick::ORIENTATION_TOPLEFT);
    }
915330
public function rotate(float $degrees)
    {
        $degrees = 360 - $degrees; // match imagick
        $this->data = imagerotate($this->data, $degrees, 0);
    }