105 lines
3.2 KiB
PHP
105 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace Aweos\Resizer\Classes;
|
|
|
|
use Aweos\Resizer\Compressors\Compressor;
|
|
use Aweos\Resizer\Exceptions\ResizerException;
|
|
use Aweos\Resizer\Lib\MediaPath;
|
|
use Aweos\Resizer\Models\Setting;
|
|
use Illuminate\Filesystem\FilesystemAdapter;
|
|
use Illuminate\Support\Collection;
|
|
|
|
class ImageResizer
|
|
{
|
|
private FilesystemAdapter $disk;
|
|
private string $uploadDir;
|
|
private MediaPath $file;
|
|
private bool $update;
|
|
private Compressor $compressor;
|
|
|
|
public function __construct(FilesystemAdapter $disk, string $uploadDir)
|
|
{
|
|
$this->disk = $disk;
|
|
$this->uploadDir = $uploadDir;
|
|
}
|
|
|
|
public function generate(MediaPath $file, bool $update): void
|
|
{
|
|
$this->file = $file;
|
|
$this->compressor = $this->file->compressor();
|
|
$this->update = $update;
|
|
|
|
if (!$file->exists()) {
|
|
throw new ResizerException('File versions cannot be generated. Root file "'.$file->root().'" doesnt exist.');
|
|
}
|
|
|
|
if ($this->compressor->shouldGenerateVersions()) {
|
|
$this->compressor->start();
|
|
$this->generateVersions();
|
|
$this->compressor->end();
|
|
}
|
|
}
|
|
|
|
private function dimensions(): Collection
|
|
{
|
|
[$width, $height] = $this->compressor->originalSize();
|
|
|
|
return collect(compact('width', 'height'));
|
|
}
|
|
|
|
private function sizes(): Collection
|
|
{
|
|
$sizes = Setting::get('sizes');
|
|
|
|
return collect(array_column($sizes, 'aspect_ratio'))->map(
|
|
fn ($ratio) => collect(array_combine(['width', 'height'], explode('x', $ratio))),
|
|
);
|
|
}
|
|
|
|
private function possibleSizes(): Collection
|
|
{
|
|
$return = collect([]);
|
|
$ratios = collect();
|
|
$dimensions = $this->dimensions();
|
|
$ratios->push($dimensions);
|
|
$ratios = $ratios->merge($this->sizes());
|
|
|
|
foreach (collect(Setting::get('breakpoints'))->push($dimensions->get('width'))->unique() as $size) {
|
|
foreach ($ratios as $ratio) {
|
|
$width = $size;
|
|
$height = $size * $ratio->get('height') / $ratio->get('width');
|
|
|
|
if ($height > $dimensions->get('height')) {
|
|
$width = $width * $dimensions->get('height') / $height;
|
|
$height = $dimensions->get('height');
|
|
}
|
|
|
|
if (ceil($width) > $dimensions->get('width') || ceil($height) > $dimensions->get('height')) {
|
|
continue;
|
|
}
|
|
|
|
$return->push(collect([
|
|
'width' => round($width),
|
|
'height' => round($height),
|
|
]));
|
|
}
|
|
}
|
|
|
|
return $return;
|
|
}
|
|
|
|
private function generateVersions(): void
|
|
{
|
|
foreach ($this->possibleSizes() as $size) {
|
|
$this->compressor->resize($size, $this->update, function ($media, $file) {
|
|
if (!file_exists($file)) {
|
|
throw new ResizerException('File versions cannot be generated. Version file "'.$file.'" of "'.$this->file->root().'" doesnt exist.');
|
|
}
|
|
if (file_exists($file) || !$this->update) {
|
|
$this->compressor->make($file);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|