This commit is contained in:
root
2025-11-13 19:52:28 +03:00
parent 8aeeb05b7d
commit 807dec3b6c
4646 changed files with 163445 additions and 626017 deletions

View File

@@ -184,6 +184,16 @@ class Image
return $this->engine->resize($source, $destination);
}
/**
* Blurs the image.
* @param int $sigma
* @return bool
*/
public function blur(int $sigma): bool
{
return $this->engine->blur($sigma);
}
/**
* Applies a mask to the image (convolution).
* @param Image\Mask $mask

View File

@@ -198,6 +198,15 @@ abstract class Engine
*/
abstract public function resize(Rectangle $source, Rectangle $destination);
/**
* Blur the image.
*
* @param int $sigma
*
* @return bool
*/
abstract public function blur(int $sigma): bool;
/**
* Applies a mask to the image (convolution).
* @param Mask $mask

View File

@@ -173,6 +173,72 @@ class Gd extends Engine
return false;
}
/**
* @inheritDoc
*/
public function blur(int $sigma): bool
{
if ($this->resource === null)
{
return false;
}
$sigma = max(1, min(100, round($sigma)));
$originalWidth = $this->getWidth();
$originalHeight = $this->getHeight();
$minScale = 0.5;
$smallestWidth = ceil($originalWidth * (1 - pow($minScale, 1.0 / $sigma)));
$smallestHeight = ceil($originalHeight * (1 - pow($minScale, 1.0 / $sigma)));
$prevImage = $this->resource;
$prevWidth = $originalWidth;
$prevHeight = $originalHeight;
$nextImage = $this->resource;
$nextWidth = 0;
$nextHeight = 0;
for ($i = 1; $i <= $sigma; $i += 1)
{
$denominator = (1 - pow($minScale, 1.0 / $i));
$nextWidth = (int)round($smallestWidth / $denominator);
$nextHeight = (int)round($smallestHeight / $denominator);
$nextImage = imagecreatetruecolor($nextWidth, $nextHeight);
if ($this->format == File\Image::FORMAT_PNG || $this->format == File\Image::FORMAT_WEBP)
{
imagealphablending($nextImage, false);
imagesavealpha($nextImage, true);
}
imagecopyresampled($nextImage, $prevImage, 0, 0, 0, 0, $nextWidth, $nextHeight, $prevWidth, $prevHeight);
imagefilter($nextImage, IMG_FILTER_GAUSSIAN_BLUR);
if ($prevImage !== $this->resource)
{
imagedestroy($prevImage);
}
$prevImage = $nextImage;
$prevWidth = $nextWidth;
$prevHeight = $nextHeight;
}
if ($this->format == File\Image::FORMAT_PNG || $this->format == File\Image::FORMAT_WEBP)
{
imagealphablending($this->resource, false);
imagesavealpha($this->resource, true);
}
imagecopyresampled($this->resource, $nextImage, 0, 0, 0, 0, $originalWidth, $originalHeight, $nextWidth, $nextHeight);
imagefilter($this->resource, IMG_FILTER_GAUSSIAN_BLUR);
if ($nextImage !== $this->resource)
{
imagedestroy($nextImage);
}
return true;
}
/**
* @inheritDoc
*/

View File

@@ -264,6 +264,22 @@ class Imagick extends Engine
return true;
}
/**
* @inheritDoc
*/
public function blur(int $sigma): bool
{
if ($this->image === null)
{
return false;
}
$sigma = max(1, min(100, round($sigma)));
$this->image->blurImage(0, $sigma);
return true;
}
/**
* @inheritDoc
*/