Completed
Push — master ( c2f76d...03586b )
by Freek
11:35
created

calculateWidths()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.9713
c 0
b 0
f 0
cc 3
eloc 13
nc 3
nop 3
1
<?php
2
3
namespace Spatie\MediaLibrary\ResponsiveImages\WidthCalculator;
4
5
use Illuminate\Support\Collection;
6
use Spatie\Image\Image;
7
use Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\WidthCalculator;
8
9
class FileSizeOptimizedWidthCalculator implements WidthCalculator
10
{
11
    public function calculateWidthsFromFile(string $imagePath): Collection
12
    {
13
        $image = Image::load($imagePath);
14
        
15
        $width = $image->getWidth();
16
        $height = $image->getHeight();
17
        $fileSize = filesize($imagePath);
18
19
        return $this->calculateWidths($fileSize, $width, $height);
20
    }
21
22
    public function calculateWidths(int $fileSize, int $width, int $height): Collection
23
    {
24
        $targetWidths = collect();
25
26
        $targetWidths->push($width);
27
28
        $ratio = $height / $width;
29
        $area = $width * $width * $ratio;
30
31
        $predictedFileSize = $fileSize;
32
        $pixelPrice = $predictedFileSize / $area;
33
34
        while (true) {
35
            $predictedFileSize *= 0.7;
36
37
            $newWidth = (int)floor(sqrt(($predictedFileSize / $pixelPrice) / $ratio));
38
39
            if ($this->finishedCalculating($predictedFileSize, $newWidth)) {
40
                return $targetWidths;
41
            }
42
43
            $targetWidths->push($newWidth);
44
        }
45
    }
46
47
    protected function finishedCalculating(int $predictedFileSize, int $newWidth): bool
48
    {
49
        if ($newWidth < 20) {
50
            return true;
51
        }
52
53
        if ($predictedFileSize < (1024 * 10)) {
54
            return true;
55
        }
56
57
        return false;
58
    }
59
}
60