|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Spatie\MediaLibrary\ResponsiveImages; |
|
4
|
|
|
|
|
5
|
|
|
use Spatie\MediaLibrary\Helpers\File; |
|
6
|
|
|
use Spatie\MediaLibrary\Models\Media; |
|
7
|
|
|
use Spatie\MediaLibrary\Helpers\ImageFactory; |
|
8
|
|
|
use Spatie\MediaLibrary\Conversion\Conversion; |
|
9
|
|
|
use Spatie\MediaLibrary\Filesystem\Filesystem; |
|
10
|
|
|
use Spatie\MediaLibrary\Helpers\TemporaryDirectory; |
|
11
|
|
|
use Spatie\MediaLibrary\Events\ResponsiveImagesGenerated; |
|
12
|
|
|
use Spatie\MediaLibrary\ResponsiveImages\Exceptions\InvalidTinyJpg; |
|
13
|
|
|
use Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\WidthCalculator; |
|
14
|
|
|
use Spatie\TemporaryDirectory\TemporaryDirectory as BaseTemporaryDirectory; |
|
15
|
|
|
use Spatie\MediaLibrary\ResponsiveImages\TinyPlaceholderGenerator\TinyPlaceholderGenerator; |
|
16
|
|
|
|
|
17
|
|
|
class ResponsiveImageGenerator |
|
18
|
|
|
{ |
|
19
|
|
|
/** \Spatie\MediaLibrary\Filesystem\Filesystem */ |
|
20
|
|
|
protected $filesystem; |
|
21
|
|
|
|
|
22
|
|
|
/** \Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\WidthCalculator */ |
|
23
|
|
|
protected $widthCalculator; |
|
24
|
|
|
|
|
25
|
|
|
/** \Spatie\MediaLibrary\ResponsiveImages\TinyPlaceHolderGenerator\TinyPlaceHolderGenerator */ |
|
26
|
|
|
protected $tinyPlaceholderGenerator; |
|
27
|
|
|
|
|
28
|
|
|
public function __construct( |
|
29
|
|
|
Filesystem $filesystem, |
|
30
|
|
|
WidthCalculator $widthCalculator, |
|
31
|
|
|
TinyPlaceholderGenerator $tinyPlaceholderGenerator |
|
32
|
|
|
) { |
|
33
|
|
|
$this->filesystem = $filesystem; |
|
34
|
|
|
|
|
35
|
|
|
$this->widthCalculator = $widthCalculator; |
|
36
|
|
|
|
|
37
|
|
|
$this->tinyPlaceholderGenerator = $tinyPlaceholderGenerator; |
|
38
|
|
|
} |
|
39
|
|
|
|
|
40
|
|
|
public function generateResponsiveImages(Media $media) |
|
41
|
|
|
{ |
|
42
|
|
|
$temporaryDirectory = TemporaryDirectory::create(); |
|
43
|
|
|
|
|
44
|
|
|
$baseImage = app(Filesystem::class)->copyFromMediaLibrary( |
|
45
|
|
|
$media, |
|
46
|
|
|
$temporaryDirectory->path(str_random(16).'.'.$media->extension) |
|
|
|
|
|
|
47
|
|
|
); |
|
48
|
|
|
|
|
49
|
|
|
$media = $this->cleanResponsiveImages($media); |
|
50
|
|
|
|
|
51
|
|
|
foreach ($this->widthCalculator->calculateWidthsFromFile($baseImage) as $width) { |
|
52
|
|
|
$this->generateResponsiveImage($media, $baseImage, 'medialibrary_original', $width, $temporaryDirectory); |
|
53
|
|
|
} |
|
54
|
|
|
|
|
55
|
|
|
event(new ResponsiveImagesGenerated($media)); |
|
56
|
|
|
|
|
57
|
|
|
$this->generateTinyJpg($media, $baseImage, 'medialibrary_original', $temporaryDirectory); |
|
58
|
|
|
|
|
59
|
|
|
$temporaryDirectory->delete(); |
|
60
|
|
|
} |
|
61
|
|
|
|
|
62
|
|
|
public function generateResponsiveImagesForConversion(Media $media, Conversion $conversion, string $baseImage) |
|
63
|
|
|
{ |
|
64
|
|
|
$temporaryDirectory = TemporaryDirectory::create(); |
|
65
|
|
|
|
|
66
|
|
|
$media = $this->cleanResponsiveImages($media, $conversion->getName()); |
|
67
|
|
|
|
|
68
|
|
|
foreach ($this->widthCalculator->calculateWidthsFromFile($baseImage) as $width) { |
|
69
|
|
|
$this->generateResponsiveImage($media, $baseImage, $conversion->getName(), $width, $temporaryDirectory); |
|
70
|
|
|
} |
|
71
|
|
|
|
|
72
|
|
|
$this->generateTinyJpg($media, $baseImage, $conversion->getName(), $temporaryDirectory); |
|
73
|
|
|
|
|
74
|
|
|
$temporaryDirectory->delete(); |
|
75
|
|
|
} |
|
76
|
|
|
|
|
77
|
|
|
public function generateResponsiveImage( |
|
78
|
|
|
Media $media, |
|
79
|
|
|
string $baseImage, |
|
80
|
|
|
string $conversionName, |
|
81
|
|
|
int $targetWidth, |
|
82
|
|
|
BaseTemporaryDirectory $temporaryDirectory |
|
83
|
|
|
) { |
|
84
|
|
|
$responsiveImagePath = $this->appendToFileName($media->file_name, "___{$conversionName}_{$targetWidth}"); |
|
85
|
|
|
|
|
86
|
|
|
$tempDestination = $temporaryDirectory->path($responsiveImagePath); |
|
87
|
|
|
|
|
88
|
|
|
ImageFactory::load($baseImage) |
|
|
|
|
|
|
89
|
|
|
->optimize() |
|
90
|
|
|
->width($targetWidth) |
|
91
|
|
|
->save($tempDestination); |
|
92
|
|
|
|
|
93
|
|
|
$responsiveImageHeight = ImageFactory::load($tempDestination)->getHeight(); |
|
94
|
|
|
|
|
95
|
|
|
$finalImageFileName = $this->appendToFileName($responsiveImagePath, "_{$responsiveImageHeight}"); |
|
96
|
|
|
|
|
97
|
|
|
$finalResponsiveImagePath = $temporaryDirectory->path($finalImageFileName); |
|
98
|
|
|
|
|
99
|
|
|
rename($tempDestination, $finalResponsiveImagePath); |
|
100
|
|
|
|
|
101
|
|
|
$this->filesystem->copyToMediaLibrary($finalResponsiveImagePath, $media, 'responsiveImages'); |
|
102
|
|
|
|
|
103
|
|
|
ResponsiveImage::register($media, $finalImageFileName, $conversionName); |
|
104
|
|
|
} |
|
105
|
|
|
|
|
106
|
|
|
public function generateTinyJpg(Media $media, string $originalImagePath, string $conversionName, BaseTemporaryDirectory $temporaryDirectory) |
|
107
|
|
|
{ |
|
108
|
|
|
$tempDestination = $temporaryDirectory->path('tiny.jpg'); |
|
109
|
|
|
|
|
110
|
|
|
$this->tinyPlaceholderGenerator->generateTinyPlaceholder($originalImagePath, $tempDestination); |
|
111
|
|
|
|
|
112
|
|
|
$this->guardAgainstInvalidTinyPlaceHolder($tempDestination); |
|
113
|
|
|
|
|
114
|
|
|
$tinyImageDataBase64 = base64_encode(file_get_contents($tempDestination)); |
|
115
|
|
|
|
|
116
|
|
|
$tinyImageBase64 = 'data:image/jpeg;base64,'.$tinyImageDataBase64; |
|
117
|
|
|
|
|
118
|
|
|
$originalImage = ImageFactory::load($originalImagePath); |
|
119
|
|
|
|
|
120
|
|
|
$originalImageWidth = $originalImage->getWidth(); |
|
121
|
|
|
|
|
122
|
|
|
$originalImageHeight = $originalImage->getHeight(); |
|
123
|
|
|
|
|
124
|
|
|
$svg = view('medialibrary::placeholderSvg', compact( |
|
125
|
|
|
'originalImageWidth', |
|
126
|
|
|
'originalImageHeight', |
|
127
|
|
|
'tinyImageBase64' |
|
128
|
|
|
)); |
|
129
|
|
|
|
|
130
|
|
|
$base64Svg = 'data:image/svg+xml;base64,'.base64_encode($svg); |
|
131
|
|
|
|
|
132
|
|
|
ResponsiveImage::registerTinySvg($media, $base64Svg, $conversionName); |
|
133
|
|
|
} |
|
134
|
|
|
|
|
135
|
|
|
protected function appendToFileName(string $filePath, string $suffix): string |
|
136
|
|
|
{ |
|
137
|
|
|
$baseName = pathinfo($filePath, PATHINFO_FILENAME); |
|
138
|
|
|
|
|
139
|
|
|
$extension = pathinfo($filePath, PATHINFO_EXTENSION); |
|
140
|
|
|
|
|
141
|
|
|
return $baseName.$suffix.'.'.$extension; |
|
142
|
|
|
} |
|
143
|
|
|
|
|
144
|
|
|
protected function guardAgainstInvalidTinyPlaceHolder(string $tinyPlaceholderPath) |
|
145
|
|
|
{ |
|
146
|
|
|
if (! file_exists($tinyPlaceholderPath)) { |
|
147
|
|
|
throw InvalidTinyJpg::doesNotExist($tinyPlaceholderPath); |
|
148
|
|
|
} |
|
149
|
|
|
|
|
150
|
|
|
$mimeType = File::getMimetype($tinyPlaceholderPath); |
|
151
|
|
|
|
|
152
|
|
|
if ($mimeType !== 'image/jpeg') { |
|
153
|
|
|
throw InvalidTinyJpg::hasWrongMimeType($tinyPlaceholderPath); |
|
154
|
|
|
} |
|
155
|
|
|
} |
|
156
|
|
|
|
|
157
|
|
|
protected function cleanResponsiveImages(Media $media, string $conversionName = 'medialibrary_original') : Media |
|
158
|
|
|
{ |
|
159
|
|
|
$responsiveImages = $media->responsive_images; |
|
160
|
|
|
$responsiveImages[$conversionName]['urls'] = []; |
|
161
|
|
|
$media->responsive_images = $responsiveImages; |
|
162
|
|
|
|
|
163
|
|
|
$this->filesystem->removeResponsiveImages($media, $conversionName); |
|
164
|
|
|
|
|
165
|
|
|
return $media; |
|
166
|
|
|
} |
|
167
|
|
|
} |
|
168
|
|
|
|
This function has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.