128 if ($this->resource ===
null)
133 $destinationWidth = $destination->
getWidth();
134 $destinationHeight = $destination->
getHeight();
136 if (($picture = imagecreatetruecolor($destinationWidth, $destinationHeight)))
138 $transparentColor = -1;
140 imagealphablending($picture,
false);
142 if ($this->format ==
File\Image::FORMAT_PNG || $this->format ==
File\Image::FORMAT_WEBP)
144 $color = imagecolorallocatealpha($picture, 0, 0, 0, 127);
145 imagefilledrectangle($picture, 0, 0, $destinationWidth, $destinationHeight, $color);
147 elseif ($this->format ==
File\Image::FORMAT_GIF)
151 if ($transparentColor >= 0)
153 $rgb = imagecolorsforindex($this->resource, $transparentColor);
154 $transparentColor = imagecolorallocatealpha($picture, $rgb[
'red'], $rgb[
'green'], $rgb[
'blue'], 127);
155 imagefilledrectangle($picture, 0, 0, $destinationWidth, $destinationHeight, $transparentColor);
159 if (imagecopyresampled($picture, $this->resource, 0, 0, $source->
getX(), $source->
getY(), $destinationWidth, $destinationHeight, $source->
getWidth(), $source->
getHeight()))
162 $this->resource = $picture;
165 if ($transparentColor >= 0)
179 public function blur(
int $sigma): bool
181 if ($this->resource ===
null)
186 $sigma = max(1, min(100, round($sigma)));
192 $smallestWidth = ceil(
$originalWidth * (1 - pow($minScale, 1.0 / $sigma)));
193 $smallestHeight = ceil(
$originalHeight * (1 - pow($minScale, 1.0 / $sigma)));
202 for (
$i = 1;
$i <= $sigma;
$i += 1)
204 $denominator = (1 - pow($minScale, 1.0 /
$i));
205 $nextWidth = (int)round($smallestWidth / $denominator);
206 $nextHeight = (int)round($smallestHeight / $denominator);
207 $nextImage = imagecreatetruecolor($nextWidth, $nextHeight);
208 if ($this->format ==
File\Image::FORMAT_PNG || $this->format ==
File\Image::FORMAT_WEBP)
210 imagealphablending($nextImage,
false);
211 imagesavealpha($nextImage,
true);
214 imagecopyresampled($nextImage, $prevImage, 0, 0, 0, 0, $nextWidth, $nextHeight, $prevWidth, $prevHeight);
215 imagefilter($nextImage, IMG_FILTER_GAUSSIAN_BLUR);
216 if ($prevImage !== $this->resource)
218 imagedestroy($prevImage);
221 $prevImage = $nextImage;
222 $prevWidth = $nextWidth;
223 $prevHeight = $nextHeight;
226 if ($this->format ==
File\Image::FORMAT_PNG || $this->format ==
File\Image::FORMAT_WEBP)
228 imagealphablending($this->resource,
false);
229 imagesavealpha($this->resource,
true);
233 imagefilter($this->resource, IMG_FILTER_GAUSSIAN_BLUR);
234 if ($nextImage !== $this->resource)
236 imagedestroy($nextImage);
247 if ($this->resource ===
null)
252 $transparentColor = -1;
253 if ($this->format ==
File\Image::FORMAT_GIF)
267 imagealphablending($this->resource,
false);
268 imagesetpixel($this->resource, 0, 0, $newPixel);
271 if ($transparentColor >= 0)
291 imagecolortransparent($this->resource, $transparentColor);
296 for ($y = 0; $y < $height; ++$y)
298 for ($x = 0; $x <
$width; ++$x)
300 if (((imagecolorat($this->resource, $x, $y) >> 24) & 0x7F) >= 100)
302 imagesetpixel($this->resource, $x, $y, $transparentColor);
319 $alpha = (imagecolorat($this->resource, $x, $y) >> 24) & 0xFF;
320 $newR = $newG = $newB = 0;
322 for ($j = 0; $j < 3; ++$j)
334 for (
$i = 0;
$i < 3; ++
$i)
347 $rgb = imagecolorat($this->resource, $xv, $yv);
349 $newR += (($rgb >> 16) & 0xFF) * $m;
350 $newG += (($rgb >> 8) & 0xFF) * $m;
351 $newB += ($rgb & 0xFF) * $m;
355 $newR = ($newR > 255 ? 255 : ($newR < 0 ? 0 : $newR));
356 $newG = ($newG > 255 ? 255 : ($newG < 0 ? 0 : $newG));
357 $newB = ($newB > 255 ? 255 : ($newB < 0 ? 0 : $newB));
359 return imagecolorallocatealpha($this->resource, $newR, $newG, $newB, $alpha);
367 if ($this->resource ===
null)
374 if (!file_exists($font))
386 $textBox = imagettfbbox(20, 0, $font, $utfText);
387 if (!is_array($textBox))
392 $scale =
$textWidth / ($textBox[2] - $textBox[0]);
401 $textBox = imagettfbbox(
$fontSize, 0, $font, $utfText);
403 $position =
new Rectangle(($textBox[2] - $textBox[0]), ($textBox[0] - $textBox[7]));
409 $textColor = imagecolorallocate($this->resource, $color->getRed(), $color->getGreen(), $color->getBlue());
417 $y = $position->getY() + $position->getHeight() - $descender;
424 $result = imagettftext($this->resource,
$fontSize, 0, $position->getX(), $y, $textColor, $font, $utfText);
434 if ($this->resource ===
null)
447 $watermarkWidth = $image->getWidth();
448 $watermarkHeight = $image->getHeight();
450 $position =
new Rectangle($watermarkWidth, $watermarkHeight);
454 $watermarkX = $position->getX();
455 $watermarkY = $position->getY();
457 $watermarkAlpha = $watermark->
getAlpha();
460 for ($y = 0; $y < $watermarkHeight; $y++)
462 for ($x = 0; $x < $watermarkWidth; $x++)
464 $posY = $watermarkY + $y;
467 $posX = $watermarkX + $x;
470 $alpha = $watermarkAlpha;
472 $mainRgb = imagecolorsforindex($this->resource, imagecolorat($this->resource, $posX, $posY));
473 $watermarkRgb = imagecolorsforindex($image->resource, imagecolorat($image->resource, $x, $y));
475 if ($watermarkRgb[
'alpha'] == 127)
481 if ($watermarkRgb[
'alpha'])
483 $alpha = round((( 127 - $watermarkRgb[
'alpha']) / 127), 2);
484 $alpha = $alpha * $watermarkAlpha;
488 foreach ([
'red',
'green',
'blue',
'alpha'] as
$k)
490 $pixel[
$k] = round(($mainRgb[
$k] * (1 - $alpha)) + ($watermarkRgb[
$k] * $alpha));
494 $color = imagecolorexactalpha($this->resource, $pixel[
'red'], $pixel[
'green'], $pixel[
'blue'], $pixel[
'alpha']);
497 $color = imagecolorallocatealpha($this->resource, $pixel[
'red'], $pixel[
'green'], $pixel[
'blue'], $pixel[
'alpha']);
498 if ($color ===
false)
500 $color = imagecolorclosestalpha($this->resource, $pixel[
'red'], $pixel[
'green'], $pixel[
'blue'], $pixel[
'alpha']);
504 imagesetpixel($this->resource, $posX, $posY, $color);
506 $posX += $watermarkWidth;
508 if (!$repeat || $posX >
$width)
514 $posY += $watermarkHeight;
516 if (!$repeat || $posY > $height)
534 if ($this->resource ===
null)
548 case File\Image::FORMAT_GIF:
551 case File\Image::FORMAT_PNG:
552 imagealphablending($this->resource,
true);
553 imagesavealpha($this->resource,
true);
556 case File\Image::FORMAT_WEBP:
557 imagealphablending($this->resource,
true);
558 imagesavealpha($this->resource,
true);
561 case File\Image::FORMAT_BMP:
564 case File\Image::FORMAT_JPEG: