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

FileSizeOptimizedWidthCalculator   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 51
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 7
lcom 1
cbo 2
dl 0
loc 51
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A calculateWidthsFromFile() 0 10 1
B calculateWidths() 0 24 3
A finishedCalculating() 0 12 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