gradient/src/GradientImage.php

56 lines
1.7 KiB
PHP

<?php
namespace Zoomyboy\Gradient;
use GdImage;
use Illuminate\Http\UploadedFile;
class GradientImage
{
public function generate(int $image_width, int $image_height, string $from, string $to, Degree $degree, Prop $prop = Prop::LINEAR): UploadedFile
{
$filename = (string) str("{$from}-{$to}.png")->replace('#', '');
$from = $this->toRgb($from);
$to = $this->toRgb($to);
$image = imagecreatetruecolor($image_width, $image_height);
$image = $this->makeGradient($image, $from, $to, $prop->calculatorCallback());
$image = imagerotate($image, 360 - $degree->value, 0);
imagepng($image, "/tmp/{$filename}");
imagedestroy($image);
return new UploadedFile("/tmp/{$filename}", $filename, 'image/png');
}
public function toRgb(string $hexColor): RgbColor
{
$hexColor = substr($hexColor, 1);
$colors = collect(str_split($hexColor, 2))
->map(fn ($hex) => hexdec($hex))
->toArray();
return new RgbColor(...$colors);
}
private function makeGradient(GdImage $image, RgbColor $from, RgbColor $to, callable $calculator): GdImage
{
$image_width = imagesx($image);
$image_height = imagesy($image);
for ($i = 0; $i < $image_height; ++$i) {
$percent = $calculator($i, $image_height);
$color_r = (int) floor(($from->r - $to->r) * $percent) + $to->r;
$color_g = (int) floor(($from->g - $to->g) * $percent) + $to->g;
$color_b = (int) floor(($from->b - $to->b) * $percent) + $to->b;
$color = imagecolorallocate($image, $color_r, $color_g, $color_b);
imageline($image, 0, $i, $image_width, $i, $color);
}
return $image;
}
}