One Hat Cyber Team
Your IP:
216.73.216.102
Server IP:
198.54.114.155
Server:
Linux server71.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64
Server Software:
LiteSpeed
PHP Version:
5.6.40
Create File
|
Create Folder
Execute
Dir :
~
/
home
/
fluxyjvi
/
public_html
/
assets
/
images
/
View File Name :
image.tar
src/Exceptions/CouldNotConvert.php 0000644 00000000434 15107356727 0013273 0 ustar 00 <?php namespace Spatie\Image\Exceptions; use Exception; class CouldNotConvert extends Exception { public static function unknownManipulation(string $operationName): self { return new self("Can not convert image. Unknown operation `{$operationName}` used"); } } src/Exceptions/InvalidImageDriver.php 0000644 00000000402 15107356727 0013703 0 ustar 00 <?php namespace Spatie\Image\Exceptions; use Exception; class InvalidImageDriver extends Exception { public static function driver(string $driver): self { return new self("Driver must be `gd` or `imagick`. `{$driver}` provided."); } } src/Exceptions/InvalidTemporaryDirectory.php 0000644 00000000772 15107356727 0015366 0 ustar 00 <?php namespace Spatie\Image\Exceptions; use Exception; class InvalidTemporaryDirectory extends Exception { public static function temporaryDirectoryNotCreatable(string $directory): self { return new self("the temporary directory `{$directory}` does not exist and can not be created"); } public static function temporaryDirectoryNotWritable(string $directory): self { return new self("the temporary directory `{$directory}` does exist but is not writable"); } } src/Exceptions/InvalidManipulation.php 0000644 00000002305 15107356727 0014151 0 ustar 00 <?php namespace Spatie\Image\Exceptions; use Exception; class InvalidManipulation extends Exception { public static function invalidWidth(int $width): self { return new self("Width should be a positive number. `{$width}` given."); } public static function invalidHeight(int $height): self { return new self("Height should be a positive number. `{$height}` given."); } public static function invalidParameter(string $name, $invalidValue, array $validValues): self { $validValues = self::formatValues($validValues); $name = ucfirst($name); return new self("{$name} should be one of {$validValues}. `{$invalidValue}` given."); } public static function valueNotInRange(string $name, $invalidValue, $minValue, $maxValue): self { $name = ucfirst($name); return new self("{$name} should be a number in the range {$minValue} until {$maxValue}. `{$invalidValue}` given."); } protected static function formatValues(array $values): string { $quotedValues = array_map(function (string $value) { return "`{$value}`"; }, $values); return implode(', ', $quotedValues); } } src/Manipulations.php 0000644 00000043135 15107356727 0010712 0 ustar 00 <?php namespace Spatie\Image; use League\Glide\Filesystem\FileNotFoundException; use ReflectionClass; use Spatie\Image\Exceptions\InvalidManipulation; class Manipulations { public const CROP_TOP_LEFT = 'crop-top-left'; public const CROP_TOP = 'crop-top'; public const CROP_TOP_RIGHT = 'crop-top-right'; public const CROP_LEFT = 'crop-left'; public const CROP_CENTER = 'crop-center'; public const CROP_RIGHT = 'crop-right'; public const CROP_BOTTOM_LEFT = 'crop-bottom-left'; public const CROP_BOTTOM = 'crop-bottom'; public const CROP_BOTTOM_RIGHT = 'crop-bottom-right'; public const ORIENTATION_AUTO = 'auto'; public const ORIENTATION_0 = 0; public const ORIENTATION_90 = 90; public const ORIENTATION_180 = 180; public const ORIENTATION_270 = 270; public const FLIP_HORIZONTALLY = 'h'; public const FLIP_VERTICALLY = 'v'; public const FLIP_BOTH = 'both'; public const FIT_CONTAIN = 'contain'; public const FIT_MAX = 'max'; public const FIT_FILL = 'fill'; public const FIT_FILL_MAX = 'fill-max'; public const FIT_STRETCH = 'stretch'; public const FIT_CROP = 'crop'; public const BORDER_OVERLAY = 'overlay'; public const BORDER_SHRINK = 'shrink'; public const BORDER_EXPAND = 'expand'; public const FORMAT_JPG = 'jpg'; public const FORMAT_PJPG = 'pjpg'; public const FORMAT_PNG = 'png'; public const FORMAT_GIF = 'gif'; public const FORMAT_WEBP = 'webp'; public const FORMAT_AVIF = 'avif'; public const FORMAT_TIFF = 'tiff'; public const FILTER_GREYSCALE = 'greyscale'; public const FILTER_SEPIA = 'sepia'; public const UNIT_PIXELS = 'px'; public const UNIT_PERCENT = '%'; public const POSITION_TOP_LEFT = 'top-left'; public const POSITION_TOP = 'top'; public const POSITION_TOP_RIGHT = 'top-right'; public const POSITION_LEFT = 'left'; public const POSITION_CENTER = 'center'; public const POSITION_RIGHT = 'right'; public const POSITION_BOTTOM_LEFT = 'bottom-left'; public const POSITION_BOTTOM = 'bottom'; public const POSITION_BOTTOM_RIGHT = 'bottom-right'; protected ManipulationSequence $manipulationSequence; public function __construct(array $manipulations = []) { if (! $this->hasMultipleConversions($manipulations)) { $manipulations = [$manipulations]; } foreach ($manipulations as $manipulation) { $this->manipulationSequence = new ManipulationSequence($manipulation); } } public static function create(array $manipulations = []): Manipulations { return new self($manipulations); } /** * @throws InvalidManipulation */ public function orientation(string $orientation): static { if (! $this->validateManipulation($orientation, 'orientation')) { throw InvalidManipulation::invalidParameter( 'orientation', $orientation, $this->getValidManipulationOptions('orientation') ); } return $this->addManipulation('orientation', $orientation); } /** * @throws InvalidManipulation */ public function flip(string $orientation): static { if (! $this->validateManipulation($orientation, 'flip')) { throw InvalidManipulation::invalidParameter( 'flip', $orientation, $this->getValidManipulationOptions('flip') ); } return $this->addManipulation('flip', $orientation); } /** * @throws InvalidManipulation */ public function crop(string $cropMethod, int $width, int $height): static { if (! $this->validateManipulation($cropMethod, 'crop')) { throw InvalidManipulation::invalidParameter( 'cropmethod', $cropMethod, $this->getValidManipulationOptions('crop') ); } $this->width($width); $this->height($height); return $this->addManipulation('crop', $cropMethod); } /** * @param int $focalX Crop center X in percent * @param int $focalY Crop center Y in percent * * @throws InvalidManipulation */ public function focalCrop(int $width, int $height, int $focalX, int $focalY, float $zoom = 1): static { if ($zoom < 1 || $zoom > 100) { throw InvalidManipulation::valueNotInRange('zoom', $zoom, 1, 100); } $this->width($width); $this->height($height); return $this->addManipulation('crop', "crop-{$focalX}-{$focalY}-{$zoom}"); } /** * @throws InvalidManipulation */ public function manualCrop(int $width, int $height, int $x, int $y): static { if ($width < 0) { throw InvalidManipulation::invalidWidth($width); } if ($height < 0) { throw InvalidManipulation::invalidWidth($height); } return $this->addManipulation('manualCrop', "{$width},{$height},{$x},{$y}"); } /** * @throws InvalidManipulation */ public function width(int $width): static { if ($width < 0) { throw InvalidManipulation::invalidWidth($width); } return $this->addManipulation('width', (string)$width); } /** * @throws InvalidManipulation */ public function height(int $height): static { if ($height < 0) { throw InvalidManipulation::invalidHeight($height); } return $this->addManipulation('height', (string)$height); } /** * @throws InvalidManipulation */ public function fit(string $fitMethod, ?int $width = null, ?int $height = null): static { if (! $this->validateManipulation($fitMethod, 'fit')) { throw InvalidManipulation::invalidParameter( 'fit', $fitMethod, $this->getValidManipulationOptions('fit') ); } if ($width === null && $height === null) { throw new InvalidManipulation('Width or height or both must be provided'); } if ($width !== null) { $this->width($width); } if ($height !== null) { $this->height($height); } return $this->addManipulation('fit', $fitMethod); } /** * @param int $ratio A value between 1 and 8 * * @throws InvalidManipulation */ public function devicePixelRatio(int $ratio): static { if ($ratio < 1 || $ratio > 8) { throw InvalidManipulation::valueNotInRange('ratio', $ratio, 1, 8); } return $this->addManipulation('devicePixelRatio', (string)$ratio); } /** * @param int $brightness A value between -100 and 100 * * @throws InvalidManipulation */ public function brightness(int $brightness): static { if ($brightness < -100 || $brightness > 100) { throw InvalidManipulation::valueNotInRange('brightness', $brightness, -100, 100); } return $this->addManipulation('brightness', (string)$brightness); } /** * @param float $gamma A value between 0.01 and 9.99 * * @throws InvalidManipulation */ public function gamma(float $gamma): static { if ($gamma < 0.01 || $gamma > 9.99) { throw InvalidManipulation::valueNotInRange('gamma', $gamma, 0.01, 9.00); } return $this->addManipulation('gamma', (string)$gamma); } /** * @param int $contrast A value between -100 and 100 * * @throws InvalidManipulation */ public function contrast(int $contrast): static { if ($contrast < -100 || $contrast > 100) { throw InvalidManipulation::valueNotInRange('contrast', $contrast, -100, 100); } return $this->addManipulation('contrast', (string)$contrast); } /** * @param int $sharpen A value between 0 and 100 * * @throws InvalidManipulation */ public function sharpen(int $sharpen): static { if ($sharpen < 0 || $sharpen > 100) { throw InvalidManipulation::valueNotInRange('sharpen', $sharpen, 0, 100); } return $this->addManipulation('sharpen', (string)$sharpen); } /** * @param int $blur A value between 0 and 100 * * @throws InvalidManipulation */ public function blur(int $blur): static { if ($blur < 0 || $blur > 100) { throw InvalidManipulation::valueNotInRange('blur', $blur, 0, 100); } return $this->addManipulation('blur', (string)$blur); } /** * @param int $pixelate A value between 0 and 1000 * * @throws InvalidManipulation */ public function pixelate(int $pixelate): static { if ($pixelate < 0 || $pixelate > 1000) { throw InvalidManipulation::valueNotInRange('pixelate', $pixelate, 0, 1000); } return $this->addManipulation('pixelate', (string)$pixelate); } /** * @throws InvalidManipulation */ public function greyscale(): static { return $this->filter('greyscale'); } /** * @throws InvalidManipulation */ public function sepia(): static { return $this->filter('sepia'); } public function background(string $colorName): static { return $this->addManipulation('background', $colorName); } /** * @throws InvalidManipulation */ public function border(int $width, string $color, string $borderType = 'overlay'): static { if ($width < 0) { throw InvalidManipulation::invalidWidth($width); } if (! $this->validateManipulation($borderType, 'border')) { throw InvalidManipulation::invalidParameter( 'border', $borderType, $this->getValidManipulationOptions('border') ); } return $this->addManipulation('border', "{$width},{$color},{$borderType}"); } /** * @throws InvalidManipulation */ public function quality(int $quality): static { if ($quality < 0 || $quality > 100) { throw InvalidManipulation::valueNotInRange('quality', $quality, 0, 100); } return $this->addManipulation('quality', (string)$quality); } /** * @throws InvalidManipulation */ public function format(string $format): static { if (! $this->validateManipulation($format, 'format')) { throw InvalidManipulation::invalidParameter( 'format', $format, $this->getValidManipulationOptions('format') ); } return $this->addManipulation('format', $format); } /** * @throws InvalidManipulation */ protected function filter(string $filterName): static { if (! $this->validateManipulation($filterName, 'filter')) { throw InvalidManipulation::invalidParameter( 'filter', $filterName, $this->getValidManipulationOptions('filter') ); } return $this->addManipulation('filter', $filterName); } /** * @throws FileNotFoundException */ public function watermark(string $filePath): static { if (! file_exists($filePath)) { throw new FileNotFoundException($filePath); } $this->addManipulation('watermark', $filePath); return $this; } /** * @param int $width The width of the watermark in pixels (default) or percent. * @param string $unit The unit of the `$width` parameter. Use `Manipulations::UNIT_PERCENT` or `Manipulations::UNIT_PIXELS`. */ public function watermarkWidth(int $width, string $unit = 'px'): static { $width = ($unit === static::UNIT_PERCENT ? $width.'w' : $width); return $this->addManipulation('watermarkWidth', (string)$width); } /** * @param int $height The height of the watermark in pixels (default) or percent. * @param string $unit The unit of the `$height` parameter. Use `Manipulations::UNIT_PERCENT` or `Manipulations::UNIT_PIXELS`. */ public function watermarkHeight(int $height, string $unit = 'px'): static { $height = ($unit === static::UNIT_PERCENT ? $height.'h' : $height); return $this->addManipulation('watermarkHeight', (string)$height); } /** * @param string $fitMethod How is the watermark fitted into the watermarkWidth and watermarkHeight properties. * * @throws InvalidManipulation */ public function watermarkFit(string $fitMethod): static { if (! $this->validateManipulation($fitMethod, 'fit')) { throw InvalidManipulation::invalidParameter( 'watermarkFit', $fitMethod, $this->getValidManipulationOptions('fit') ); } return $this->addManipulation('watermarkFit', $fitMethod); } /** * @param int $xPadding How far is the watermark placed from the left and right edges of the image. * @param int|null $yPadding How far is the watermark placed from the top and bottom edges of the image. * @param string $unit Unit of the padding values. Use `Manipulations::UNIT_PERCENT` or `Manipulations::UNIT_PIXELS`. */ public function watermarkPadding(int $xPadding, int $yPadding = null, string $unit = 'px'): static { $yPadding = $yPadding ?? $xPadding; $xPadding = ($unit === static::UNIT_PERCENT ? $xPadding.'w' : $xPadding); $yPadding = ($unit === static::UNIT_PERCENT ? $yPadding.'h' : $yPadding); $this->addManipulation('watermarkPaddingX', (string)$xPadding); $this->addManipulation('watermarkPaddingY', (string)$yPadding); return $this; } /** * @throws InvalidManipulation */ public function watermarkPosition(string $position): static { if (! $this->validateManipulation($position, 'position')) { throw InvalidManipulation::invalidParameter( 'watermarkPosition', $position, $this->getValidManipulationOptions('position') ); } return $this->addManipulation('watermarkPosition', $position); } /** * Sets the opacity of the watermark. Only works with the `imagick` driver. * * @param int $opacity A value between 0 and 100. * * @throws InvalidManipulation */ public function watermarkOpacity(int $opacity): static { if ($opacity < 0 || $opacity > 100) { throw InvalidManipulation::valueNotInRange('opacity', $opacity, 0, 100); } return $this->addManipulation('watermarkOpacity', (string)$opacity); } /** * Shave off some kilobytes by optimizing the image. */ public function optimize(array $optimizationOptions = []): static { return $this->addManipulation('optimize', json_encode($optimizationOptions)); } public function apply(): static { $this->manipulationSequence->startNewGroup(); return $this; } public function toArray(): array { return $this->manipulationSequence->toArray(); } /** * Checks if the given manipulations has arrays inside or not. */ private function hasMultipleConversions(array $manipulations): bool { foreach ($manipulations as $manipulation) { if (isset($manipulation[0]) && is_array($manipulation[0])) { return true; } } return false; } public function removeManipulation(string $name): void { $this->manipulationSequence->removeManipulation($name); } public function hasManipulation(string $manipulationName): bool { return ! is_null($this->getManipulationArgument($manipulationName)); } public function getManipulationArgument(string $manipulationName) { foreach ($this->manipulationSequence->getGroups() as $manipulationSet) { if (array_key_exists($manipulationName, $manipulationSet)) { return $manipulationSet[$manipulationName]; } } } protected function addManipulation(string $manipulationName, string $manipulationArgument): static { $this->manipulationSequence->addManipulation($manipulationName, $manipulationArgument); return $this; } public function mergeManipulations(self $manipulations): static { $this->manipulationSequence->merge($manipulations->manipulationSequence); return $this; } public function getManipulationSequence(): ManipulationSequence { return $this->manipulationSequence; } protected function validateManipulation(string $value, string $constantNamePrefix): bool { return in_array($value, $this->getValidManipulationOptions($constantNamePrefix)); } protected function getValidManipulationOptions(string $manipulation): array { $options = (new ReflectionClass(static::class))->getConstants(); return array_filter($options, function ($value, $name) use ($manipulation) { return str_starts_with($name, mb_strtoupper($manipulation)); }, ARRAY_FILTER_USE_BOTH); } public function isEmpty(): bool { return $this->manipulationSequence->isEmpty(); } /* * Get the first manipulation with the given name. * * @return mixed */ public function getFirstManipulationArgument(string $manipulationName) { return $this->manipulationSequence->getFirstManipulationArgument($manipulationName); } } src/ManipulationSequence.php 0000644 00000006017 15107356727 0012216 0 ustar 00 <?php namespace Spatie\Image; use ArrayIterator; use IteratorAggregate; class ManipulationSequence implements IteratorAggregate { protected array $groups = []; public function __construct(array $sequenceArray = []) { $this->startNewGroup(); $this->mergeArray($sequenceArray); } public function addManipulation(string $operation, string $argument): static { $lastIndex = count($this->groups) - 1; $this->groups[$lastIndex][$operation] = $argument; return $this; } public function merge(self $sequence): static { $sequenceArray = $sequence->toArray(); $this->mergeArray($sequenceArray); return $this; } public function mergeArray(array $sequenceArray): void { foreach ($sequenceArray as $group) { foreach ($group as $name => $argument) { $this->addManipulation($name, $argument); } if (next($sequenceArray)) { $this->startNewGroup(); } } } public function startNewGroup(): static { $this->groups[] = []; return $this; } public function toArray(): array { return $this->getGroups(); } public function getGroups(): array { return $this->sanitizeManipulationSets($this->groups); } public function getIterator(): ArrayIterator { return new ArrayIterator($this->toArray()); } public function removeManipulation(string $manipulationName): static { foreach ($this->groups as &$group) { if (array_key_exists($manipulationName, $group)) { unset($group[$manipulationName]); } } return $this; } public function isEmpty(): bool { if (count($this->groups) > 1) { return false; } if (count($this->groups[0]) > 0) { return false; } return true; } protected function sanitizeManipulationSets(array $groups): array { return array_values(array_filter($groups, function (array $manipulationSet) { return count($manipulationSet); })); } /* * Determine if the sequences contain a manipulation with the given name. */ public function getFirstManipulationArgument($searchManipulationName) { foreach ($this->groups as $group) { foreach ($group as $name => $argument) { if ($name === $searchManipulationName) { return $argument; } } } } /* * Determine if the sequences contain a manipulation with the given name. */ public function contains($searchManipulationName): bool { foreach ($this->groups as $group) { foreach ($group as $name => $argument) { if ($name === $searchManipulationName) { return true; } } return false; } return false; } } src/Image.php 0000644 00000013226 15107356727 0007107 0 ustar 00 <?php namespace Spatie\Image; use BadMethodCallException; use Intervention\Image\ImageManagerStatic as InterventionImage; use Spatie\Image\Exceptions\InvalidImageDriver; use Spatie\ImageOptimizer\OptimizerChain; use Spatie\ImageOptimizer\OptimizerChainFactory; use Spatie\ImageOptimizer\Optimizers\BaseOptimizer; /** @mixin \Spatie\Image\Manipulations */ class Image { protected Manipulations $manipulations; protected string $imageDriver = 'gd'; protected ?string $temporaryDirectory = null; protected ?OptimizerChain $optimizerChain = null; public function __construct(protected string $pathToImage) { $this->manipulations = new Manipulations(); } public static function load(string $pathToImage): static { return new static($pathToImage); } public function setTemporaryDirectory($tempDir): static { $this->temporaryDirectory = $tempDir; return $this; } public function setOptimizeChain(OptimizerChain $optimizerChain): static { $this->optimizerChain = $optimizerChain; return $this; } /** * @param string $imageDriver * @return $this * @throws InvalidImageDriver */ public function useImageDriver(string $imageDriver): static { if (! in_array($imageDriver, ['gd', 'imagick'])) { throw InvalidImageDriver::driver($imageDriver); } $this->imageDriver = $imageDriver; InterventionImage::configure([ 'driver' => $this->imageDriver, ]); return $this; } public function manipulate(callable | Manipulations $manipulations): static { if (is_callable($manipulations)) { $manipulations($this->manipulations); } if ($manipulations instanceof Manipulations) { $this->manipulations->mergeManipulations($manipulations); } return $this; } public function __call($name, $arguments): static { if (! method_exists($this->manipulations, $name)) { throw new BadMethodCallException("Manipulation `{$name}` does not exist"); } $this->manipulations->$name(...$arguments); return $this; } public function getWidth(): int { return InterventionImage::make($this->pathToImage)->width(); } public function getHeight(): int { return InterventionImage::make($this->pathToImage)->height(); } public function getManipulationSequence(): ManipulationSequence { return $this->manipulations->getManipulationSequence(); } public function save(string $outputPath = ''): void { if ($outputPath === '') { $outputPath = $this->pathToImage; } $this->addFormatManipulation($outputPath); $glideConversion = GlideConversion::create($this->pathToImage)->useImageDriver($this->imageDriver); if (! is_null($this->temporaryDirectory)) { $glideConversion->setTemporaryDirectory($this->temporaryDirectory); } $glideConversion->performManipulations($this->manipulations); $glideConversion->save($outputPath); if ($this->shouldOptimize()) { $optimizerChainConfiguration = $this->manipulations->getFirstManipulationArgument('optimize'); $optimizerChainConfiguration = json_decode($optimizerChainConfiguration, true); $this->performOptimization($outputPath, $optimizerChainConfiguration); } } protected function shouldOptimize(): bool { return ! is_null($this->manipulations->getFirstManipulationArgument('optimize')); } protected function performOptimization($path, array $optimizerChainConfiguration): void { $optimizerChain = $this->optimizerChain ?? OptimizerChainFactory::create(); if (count($optimizerChainConfiguration)) { $existingOptimizers = $optimizerChain->getOptimizers(); $optimizers = array_map(function (array $optimizerOptions, string $optimizerClassName) use ($existingOptimizers) { $optimizer = array_values(array_filter($existingOptimizers, function ($optimizer) use ($optimizerClassName) { return $optimizer::class === $optimizerClassName; })); $optimizer = isset($optimizer[0]) && $optimizer[0] instanceof BaseOptimizer ? $optimizer[0] : new $optimizerClassName(); return $optimizer->setOptions($optimizerOptions)->setBinaryPath($optimizer->binaryPath); }, $optimizerChainConfiguration, array_keys($optimizerChainConfiguration)); $optimizerChain->setOptimizers($optimizers); } $optimizerChain->optimize($path); } protected function addFormatManipulation($outputPath): void { if ($this->manipulations->hasManipulation('format')) { return; } $inputExtension = strtolower(pathinfo($this->pathToImage, PATHINFO_EXTENSION)); $outputExtension = strtolower(pathinfo($outputPath, PATHINFO_EXTENSION)); if ($inputExtension === $outputExtension) { return; } $supportedFormats = [ Manipulations::FORMAT_JPG, Manipulations::FORMAT_PJPG, Manipulations::FORMAT_PNG, Manipulations::FORMAT_GIF, Manipulations::FORMAT_WEBP, Manipulations::FORMAT_AVIF, ]; //gd driver doesn't support TIFF if ($this->imageDriver === 'imagick') { $supportedFormats[] = Manipulations::FORMAT_TIFF; } if (in_array($outputExtension, $supportedFormats)) { $this->manipulations->format($outputExtension); } } } src/GlideConversion.php 0000644 00000013010 15107356727 0011146 0 ustar 00 <?php namespace Spatie\Image; use Exception; use FilesystemIterator; use League\Glide\Server; use League\Glide\ServerFactory; use Spatie\Image\Exceptions\CouldNotConvert; use Spatie\Image\Exceptions\InvalidTemporaryDirectory; final class GlideConversion { private string $imageDriver = 'gd'; private ?string $conversionResult = null; private string $temporaryDirectory; public function __construct(private string $inputImage) { $this->temporaryDirectory = sys_get_temp_dir(); } public static function create(string $inputImage): self { return new self($inputImage); } public function setTemporaryDirectory(string $temporaryDirectory): self { if (! is_dir($temporaryDirectory)) { try { mkdir($temporaryDirectory); } catch (Exception) { throw InvalidTemporaryDirectory::temporaryDirectoryNotCreatable($temporaryDirectory); } } if (! is_writable($temporaryDirectory)) { throw InvalidTemporaryDirectory::temporaryDirectoryNotWritable($temporaryDirectory); } $this->temporaryDirectory = $temporaryDirectory; return $this; } public function getTemporaryDirectory(): string { return $this->temporaryDirectory; } public function useImageDriver(string $imageDriver): self { $this->imageDriver = $imageDriver; return $this; } public function performManipulations(Manipulations $manipulations): GlideConversion { foreach ($manipulations->getManipulationSequence() as $manipulationGroup) { $inputFile = $this->conversionResult ?? $this->inputImage; $watermarkPath = $this->extractWatermarkPath($manipulationGroup); $glideServer = $this->createGlideServer($inputFile, $watermarkPath); $glideServer->setGroupCacheInFolders(false); $manipulatedImage = $this->temporaryDirectory.DIRECTORY_SEPARATOR.$glideServer->makeImage( pathinfo($inputFile, PATHINFO_BASENAME), $this->prepareManipulations($manipulationGroup) ); if ($this->conversionResult) { unlink($this->conversionResult); } $this->conversionResult = $manipulatedImage; } return $this; } /** * Removes the watermark path from the manipulationGroup and returns it. * This way it can be injected into the Glide server as the `watermarks` path. */ private function extractWatermarkPath(&$manipulationGroup) { if (array_key_exists('watermark', $manipulationGroup)) { $watermarkPath = dirname($manipulationGroup['watermark']); $manipulationGroup['watermark'] = basename($manipulationGroup['watermark']); return $watermarkPath; } } private function createGlideServer($inputFile, string $watermarkPath = null): Server { $config = [ 'source' => dirname($inputFile), 'cache' => $this->temporaryDirectory, 'driver' => $this->imageDriver, ]; if ($watermarkPath) { $config['watermarks'] = $watermarkPath; } return ServerFactory::create($config); } public function save(string $outputFile): void { if ($this->conversionResult === '' || $this->conversionResult === null) { copy($this->inputImage, $outputFile); return; } $conversionResultDirectory = pathinfo($this->conversionResult, PATHINFO_DIRNAME); copy($this->conversionResult, $outputFile); unlink($this->conversionResult); if ($conversionResultDirectory !== sys_get_temp_dir() && $this->directoryIsEmpty($conversionResultDirectory)) { rmdir($conversionResultDirectory); } } private function prepareManipulations(array $manipulationGroup): array { $glideManipulations = []; foreach ($manipulationGroup as $name => $argument) { if ($name !== 'optimize') { $glideManipulations[$this->convertToGlideParameter($name)] = $argument; } } return $glideManipulations; } private function convertToGlideParameter(string $manipulationName): string { return match ($manipulationName) { 'width' => 'w', 'height' => 'h', 'blur' => 'blur', 'pixelate' => 'pixel', 'crop' => 'fit', 'manualCrop' => 'crop', 'orientation' => 'or', 'flip' => 'flip', 'fit' => 'fit', 'devicePixelRatio' => 'dpr', 'brightness' => 'bri', 'contrast' => 'con', 'gamma' => 'gam', 'sharpen' => 'sharp', 'filter' => 'filt', 'background' => 'bg', 'border' => 'border', 'quality' => 'q', 'format' => 'fm', 'watermark' => 'mark', 'watermarkWidth' => 'markw', 'watermarkHeight' => 'markh', 'watermarkFit' => 'markfit', 'watermarkPaddingX' => 'markx', 'watermarkPaddingY' => 'marky', 'watermarkPosition' => 'markpos', 'watermarkOpacity' => 'markalpha', default => throw CouldNotConvert::unknownManipulation($manipulationName) }; } private function directoryIsEmpty(string $directory): bool { $iterator = new FilesystemIterator($directory); return ! $iterator->valid(); } } README.md 0000644 00000007254 15107356727 0006050 0 ustar 00 # Manipulate images with an expressive API [](https://packagist.org/packages/spatie/image) [](LICENSE.md) [](https://github.com/spatie/image/actions/workflows/run-tests.yml) [](https://packagist.org/packages/spatie/image) Image manipulation doesn't have to be hard. Here are a few examples on how this package makes it very easy to manipulate images. ```php use Spatie\Image\Image; // modifying the image so it fits in a 100x100 rectangle without altering aspect ratio Image::load($pathToImage) ->width(100) ->height(100) ->save($pathToNewImage); // overwriting the original image with a greyscale version Image::load($pathToImage) ->greyscale() ->save(); // make image darker and save it in low quality Image::load($pathToImage) ->brightness(-30) ->quality(25) ->save(); // rotate the image and sharpen it Image::load($pathToImage) ->orientation(90) ->sharpen(15) ->save(); ``` You'll find more examples in [the full documentation](https://docs.spatie.be/image). Under the hood [Glide](http://glide.thephpleague.com/) by [Jonathan Reinink](https://twitter.com/reinink) is used. ## Support us [<img src="https://github-ads.s3.eu-central-1.amazonaws.com/image.jpg?t=1" width="419px" />](https://spatie.be/github-ad-click/image) We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us). We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards). ## Installation You can install the package via composer: ``` bash composer require spatie/image ``` Please note that since version 1.5.3 this package requires exif extension to be enabled: http://php.net/manual/en/exif.installation.php ## Usage Head over to [the full documentation](https://spatie.be/docs/image). ## Changelog Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. ## Testing ``` bash composer test ``` ## Contributing Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details. ## Security If you've found a bug regarding security please mail [security@spatie.be](mailto:security@spatie.be) instead of using the issue tracker. ## Postcardware You're free to use this package, but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. Our address is: Spatie, Kruikstraat 22, 2018 Antwerp, Belgium. We publish all received postcards [on our company website](https://spatie.be/en/opensource/postcards). ## Credits - [Freek Van der Herten](https://github.com/freekmurze) - [All Contributors](../../contributors) Under the hood [Glide](http://glide.thephpleague.com/) by [Jonathan Reinink](https://twitter.com/reinink) is used. We've based our documentation and docblocks on text found in [the Glide documentation](http://glide.thephpleague.com/) ## License The MIT License (MIT). Please see [License File](LICENSE.md) for more information. composer.json 0000644 00000002457 15107356727 0007313 0 ustar 00 { "name": "spatie/image", "description": "Manipulate images with an expressive API", "keywords": [ "spatie", "image" ], "homepage": "https://github.com/spatie/image", "license": "MIT", "authors": [ { "name": "Freek Van der Herten", "email": "freek@spatie.be", "homepage": "https://spatie.be", "role": "Developer" } ], "require": { "php": "^8.0", "ext-exif": "*", "ext-mbstring": "*", "ext-json": "*", "league/glide": "^2.2.2", "spatie/image-optimizer": "^1.7", "spatie/temporary-directory": "^1.0|^2.0", "symfony/process": "^3.0|^4.0|^5.0|^6.0" }, "require-dev": { "pestphp/pest": "^1.22", "phpunit/phpunit": "^9.5", "symfony/var-dumper": "^4.0|^5.0|^6.0", "vimeo/psalm": "^4.6" }, "autoload": { "psr-4": { "Spatie\\Image\\": "src" } }, "autoload-dev": { "psr-4": { "Spatie\\Image\\Test\\": "tests" } }, "scripts": { "psalm": "vendor/bin/psalm", "test": "vendor/bin/pest" }, "config": { "sort-packages": true, "allow-plugins": { "pestphp/pest-plugin": true } } } LICENSE.md 0000644 00000002102 15107356727 0006160 0 ustar 00 The MIT License (MIT) Copyright (c) Spatie bvba <info@spatie.be> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CHANGELOG.md 0000644 00000013650 15107356727 0006377 0 ustar 00 # Changelog All notable changes to `image` will be documented in this file ## 2.2.6 - 2023-05-06 ### What's Changed - Bump dependabot/fetch-metadata from 1.3.5 to 1.3.6 by @dependabot in https://github.com/spatie/image/pull/185 - Bump dependabot/fetch-metadata from 1.3.6 to 1.4.0 by @dependabot in https://github.com/spatie/image/pull/188 - Fit with only width or height by @gdebrauwer in https://github.com/spatie/image/pull/190 ### New Contributors - @dependabot made their first contribution in https://github.com/spatie/image/pull/185 - @gdebrauwer made their first contribution in https://github.com/spatie/image/pull/190 **Full Changelog**: https://github.com/spatie/image/compare/2.2.5...2.2.6 ## 2.2.5 - 2023-01-19 ### What's Changed - Refactor tests to pest by @AyoobMH in https://github.com/spatie/image/pull/176 - Add Dependabot Automation by @patinthehat in https://github.com/spatie/image/pull/177 - Add PHP 8.2 Support by @patinthehat in https://github.com/spatie/image/pull/180 - Update Dependabot Automation by @patinthehat in https://github.com/spatie/image/pull/181 - Add fill-max fit mode by @Tofandel in https://github.com/spatie/image/pull/183 ### New Contributors - @AyoobMH made their first contribution in https://github.com/spatie/image/pull/176 - @patinthehat made their first contribution in https://github.com/spatie/image/pull/177 - @Tofandel made their first contribution in https://github.com/spatie/image/pull/183 **Full Changelog**: https://github.com/spatie/image/compare/2.2.4...2.2.5 ## 2.2.4 - 2022-08-09 ### What's Changed - Add zero orientation support ignoring EXIF by @danielcastrobalbi in https://github.com/spatie/image/pull/171 ### New Contributors - @danielcastrobalbi made their first contribution in https://github.com/spatie/image/pull/171 **Full Changelog**: https://github.com/spatie/image/compare/2.2.3...2.2.4 ## 2.2.3 - 2022-05-21 ## What's Changed - Fix permission issue with temporary directory by @sebastianpopp in https://github.com/spatie/image/pull/163 ## New Contributors - @sebastianpopp made their first contribution in https://github.com/spatie/image/pull/163 **Full Changelog**: https://github.com/spatie/image/compare/2.2.2...2.2.3 ## 2.2.2 - 2022-02-22 - add TIFF support ## 1.11.0 - 2022-02-21 ## What's Changed - Fix docs link by @pascalbaljet in https://github.com/spatie/image/pull/154 - Update .gitattributes by @PaolaRuby in https://github.com/spatie/image/pull/158 - Add TIFF support by @Synchro in https://github.com/spatie/image/pull/159 ## New Contributors - @PaolaRuby made their first contribution in https://github.com/spatie/image/pull/158 **Full Changelog**: https://github.com/spatie/image/compare/2.2.1...1.11.0 ## 2.2.1 - 2021-12-17 ## What's Changed - Use match expression in convertToGlideParameter method by @mohprilaksono in https://github.com/spatie/image/pull/149 - [REF] updated fit docs description by @JeremyRed in https://github.com/spatie/image/pull/150 - Adding compatibility to Symfony 6 by @spackmat in https://github.com/spatie/image/pull/152 ## New Contributors - @mohprilaksono made their first contribution in https://github.com/spatie/image/pull/149 - @JeremyRed made their first contribution in https://github.com/spatie/image/pull/150 - @spackmat made their first contribution in https://github.com/spatie/image/pull/152 **Full Changelog**: https://github.com/spatie/image/compare/2.2.0...2.2.1 ## 2.2.0 - 2021-10-31 - add avif support (#148) ## 2.1.0 - 2021-07-15 - Drop support for PHP 7 - Make codebase more strict with type hinting ## 2.0.0 - 2021-07-15 - Bump league/glide to v2 [#134](https://github.com/spatie/image/pull/134) ## 1.10.4 - 2021-04-07 - Allow spatie/temporary-directory v2 ## 1.10.3 - 2021-03-10 - Bump league/glide to 2.0 [#123](https://github.com/spatie/image/pull/123) ## 1.10.2 - 2020-01-26 - change condition to delete $conversionResultDirectory (#118) ## 1.10.1 - 2020-12-27 - adds zoom option to focalCrop (#112) ## 1.9.0 - 2020-11-13 - allow usage of a custom `OptimizerChain` #110 ## 1.8.1 - 2020-11-12 - revert changes from 1.8.0 ## 1.8.0 - 2020-11-12 - allow usage of a custom `OptimizerChain` (#108) ## 1.7.7 - 2020-11-12 - add support for PHP 8 ## 1.7.6 - 2020-01-26 - change uppercase function to mb_strtoupper instead of strtoupper (#99) ## 1.7.5 - 2019-11-23 - allow symfony 5 components ## 1.7.4 - 2019-08-28 - do not export docs ## 1.7.3 - 2019-08-03 - fix duplicated files (fixes #84) ## 1.7.2 - 2019-05-13 - fixes `optimize()` when used with `apply()` (#78) ## 1.7.1 - 2019-04-17 - change GlideConversion sequence (#76) ## 1.7.0 - 2019-02-22 - add support for `webp` ## 1.6.0 - 2019-01-27 - add `setTemporaryDirectory` ## 1.5.3 - 2019-01-10 - update lower deps ## 1.5.2 - 2018-05-05 - fix exception message ## 1.5.1 - 2018-04-18 - Prevent error when trying to remove `/tmp` ## 1.5.0 - 2018-04-13 - add `flip` ## 1.4.2 - 2018-04-11 - Use the correct driver for getting widths and height of images. ## 1.4.1 - 2018-02-08 - Support symfony ^4.0 - Support phpunit ^7.0 ## 1.4.0 - 2017-12-05 - add `getWidth` and `getHeight` ## 1.3.5 - 2017-12-04 - fix for problems when creating directories in the temporary directory ## 1.3.4 - 2017-07-25 - fix `optimize` docblock ## 1.3.3 - 2017-07-11 - make `optimize` method fluent ## 1.3.2 - 2017-07-05 - swap out underlying optimization package ## 1.3.1 - 2017-07-02 - internally treat `optimize` as a manipulation ## 1.3.0 - 2017-07-02 - add `optimize` method ## 1.2.1 - 2017-06-29 - add methods to determine emptyness to `Manipulations` and `ManipulationSequence` ## 1.2.0 - 2017-04-17 - allow `Manipulations` to be constructed with an array of arrays ## 1.1.3 - 2017-04-07 - improve support for multi-volume systems ## 1.1.2 - 2017-04-04 - remove conversion directory after converting image ## 1.1.1 - 2017-03-17 - avoid processing empty manipulations groups ## 1.1.0 - 2017-02-06 - added support for watermarks ## 1.0.0 - 2017-02-06 - initial release