1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* ImageWrapper.php |
4
|
|
|
* @author Revin Roman http://phptime.ru |
5
|
|
|
*/ |
6
|
|
|
|
7
|
|
|
namespace rmrevin\yii\module\File; |
8
|
|
|
|
9
|
|
|
use Imagine\Image\ImageInterface; |
10
|
|
|
use Imagine\Image\ManipulatorInterface; |
11
|
|
|
use rmrevin\yii\module\File\component\Image; |
12
|
|
|
use rmrevin\yii\module\File\models\File; |
13
|
|
|
use yii\helpers\FileHelper; |
14
|
|
|
use yii\helpers\Json; |
15
|
|
|
use yii\helpers\StringHelper; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Class ImageWrapper |
19
|
|
|
* @package rmrevin\yii\module\File |
20
|
|
|
*/ |
21
|
|
|
class ImageWrapper extends \yii\base\Object |
|
|
|
|
22
|
|
|
{ |
23
|
|
|
|
24
|
|
|
/** @var \rmrevin\yii\module\File\models\File */ |
25
|
|
|
public $File = null; |
26
|
|
|
|
27
|
|
|
/** @var array */ |
28
|
|
|
public $result = [null, null]; |
29
|
|
|
|
30
|
|
|
/** @var array */ |
31
|
|
|
private $mark = []; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* @param \rmrevin\yii\module\File\models\File $File |
35
|
|
|
* @return self |
36
|
|
|
*/ |
37
|
4 |
|
public static function load(File $File) |
38
|
|
|
{ |
39
|
4 |
|
return new self(['File' => $File]); |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @return string |
44
|
|
|
*/ |
45
|
1 |
|
public function __toString() |
46
|
|
|
{ |
47
|
1 |
|
return (string)$this->result[1]; |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* @param callable $handler |
52
|
|
|
*/ |
53
|
1 |
|
public function save($handler) |
54
|
|
|
{ |
55
|
1 |
|
$mark = $this->calculateMark(); |
56
|
|
|
|
57
|
1 |
|
$this->result = $this->getMarkedFilePath($mark); |
58
|
|
|
|
59
|
1 |
|
if (!file_exists($this->result[0])) { |
60
|
1 |
|
\Yii::trace('create new file cache:' . $this->File->id, __METHOD__); |
61
|
1 |
|
$this->createMarkedFile($handler(), $mark); |
62
|
1 |
|
} else { |
63
|
1 |
|
\Yii::trace('file already cached:' . $this->File->id . ' (' . Json::encode($this->mark) . ')', __METHOD__); |
64
|
|
|
} |
65
|
|
|
|
66
|
1 |
|
\Yii::endProfile('manipulating with file `' . $this->File->id . '`', 'services\File\models\File'); |
67
|
1 |
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* @param integer $width |
71
|
|
|
* @param integer $height |
72
|
|
|
* @param string $filter |
73
|
|
|
* @return self |
74
|
|
|
*/ |
75
|
1 |
View Code Duplication |
public function resize($width, $height, $filter = ImageInterface::FILTER_UNDEFINED) |
|
|
|
|
76
|
|
|
{ |
77
|
1 |
|
\Yii::trace('resize file', __METHOD__); |
78
|
|
|
|
79
|
1 |
|
$this->mark(__METHOD__, func_get_args()); |
80
|
|
|
$this->save(function () use ($width, $height, $filter) { |
81
|
1 |
|
return Image::resize($this->File->getAbsolutePath(), $width, $height, $filter); |
82
|
1 |
|
}); |
83
|
|
|
|
84
|
1 |
|
return $this; |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* @param integer $width |
89
|
|
|
* @param string $filter |
90
|
|
|
* @return self |
91
|
|
|
*/ |
92
|
1 |
View Code Duplication |
public function resizeByWidth($width, $filter = ImageInterface::FILTER_UNDEFINED) |
|
|
|
|
93
|
|
|
{ |
94
|
1 |
|
\Yii::trace('resizeByWidth file', __METHOD__); |
95
|
|
|
|
96
|
1 |
|
$this->mark(__METHOD__, func_get_args()); |
97
|
|
|
$this->save(function () use ($width, $filter) { |
98
|
1 |
|
return Image::resizeByWidth($this->File->getAbsolutePath(), $width, $filter); |
99
|
1 |
|
}); |
100
|
|
|
|
101
|
1 |
|
return $this; |
102
|
|
|
|
103
|
1 |
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* @param integer $height |
107
|
|
|
* @param string $filter |
108
|
|
|
* @return self |
109
|
|
|
*/ |
110
|
1 |
View Code Duplication |
public function resizeByHeight($height, $filter = ImageInterface::FILTER_UNDEFINED) |
|
|
|
|
111
|
|
|
{ |
112
|
1 |
|
\Yii::trace('resizeByHeight file', __METHOD__); |
113
|
|
|
|
114
|
1 |
|
$this->mark(__METHOD__, func_get_args()); |
115
|
|
|
$this->save(function () use ($height, $filter) { |
116
|
1 |
|
return Image::resizeByHeight($this->File->getAbsolutePath(), $height, $filter); |
117
|
1 |
|
}); |
118
|
|
|
|
119
|
1 |
|
return $this; |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* @param integer $width |
124
|
|
|
* @param integer $height |
125
|
|
|
* @param array $start |
126
|
|
|
* @return self |
127
|
|
|
*/ |
128
|
1 |
View Code Duplication |
public function crop($width, $height, array $start = [0, 0]) |
|
|
|
|
129
|
|
|
{ |
130
|
1 |
|
\Yii::trace('crop file', __METHOD__); |
131
|
|
|
|
132
|
1 |
|
$this->mark(__METHOD__, func_get_args()); |
133
|
|
|
$this->save(function () use ($width, $height, $start) { |
134
|
1 |
|
return Image::crop($this->File->getAbsolutePath(), $width, $height, $start); |
135
|
1 |
|
}); |
136
|
|
|
|
137
|
1 |
|
return $this; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* @param integer $width |
142
|
|
|
* @param integer $height |
143
|
|
|
* @param string $mode |
144
|
|
|
* @return self |
145
|
|
|
*/ |
146
|
1 |
View Code Duplication |
public function thumbnail($width, $height, $mode = ManipulatorInterface::THUMBNAIL_OUTBOUND) |
|
|
|
|
147
|
|
|
{ |
148
|
1 |
|
\Yii::trace('thumbnail file', __METHOD__); |
149
|
|
|
|
150
|
1 |
|
$this->mark(__METHOD__, func_get_args()); |
151
|
|
|
$this->save(function () use ($width, $height, $mode) { |
152
|
1 |
|
return Image::thumbnail($this->File->getAbsolutePath(), $width, $height, $mode); |
153
|
1 |
|
}); |
154
|
|
|
|
155
|
1 |
|
return $this; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* @param string $watermarkFilename |
160
|
|
|
* @param array $start |
161
|
|
|
* @return self |
162
|
|
|
*/ |
163
|
1 |
|
public function watermark($watermarkFilename, array $start = [0, 0]) |
164
|
|
|
{ |
165
|
1 |
|
\Yii::trace('watermark file', __METHOD__); |
166
|
|
|
|
167
|
1 |
|
$this->mark(__METHOD__, func_get_args()); |
168
|
|
|
$this->save(function () use ($watermarkFilename, $start) { |
169
|
1 |
|
return Image::watermark($this->File->getAbsolutePath(), $watermarkFilename, $start); |
170
|
1 |
|
}); |
171
|
|
|
|
172
|
1 |
|
return $this; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* @param string $text |
177
|
|
|
* @param string $fontFile |
178
|
|
|
* @param array $start |
179
|
|
|
* @param array $fontOptions |
180
|
|
|
* @return self |
181
|
|
|
*/ |
182
|
1 |
View Code Duplication |
public function text($text, $fontFile, array $start = [0, 0], array $fontOptions = []) |
|
|
|
|
183
|
|
|
{ |
184
|
1 |
|
\Yii::trace('text file', __METHOD__); |
185
|
|
|
|
186
|
1 |
|
$this->mark(__METHOD__, func_get_args()); |
187
|
|
|
$this->save(function () use ($text, $fontFile, $start, $fontOptions) { |
188
|
1 |
|
return Image::text($this->File->getAbsolutePath(), $text, $fontFile, $start, $fontOptions); |
189
|
1 |
|
}); |
190
|
|
|
|
191
|
1 |
|
return $this; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* @param int $margin |
196
|
|
|
* @param string $color |
197
|
|
|
* @param int $alpha |
198
|
|
|
* @return self |
199
|
|
|
*/ |
200
|
1 |
|
public function frame($margin = 20, $color = '666', $alpha = 100) |
201
|
|
|
{ |
202
|
1 |
|
\Yii::trace('frame file', __METHOD__); |
203
|
|
|
|
204
|
1 |
|
$this->mark(__METHOD__, func_get_args()); |
205
|
1 |
|
$this->save(function () use ($margin, $color, $alpha) { |
206
|
1 |
|
return Image::frame($this->File->getAbsolutePath(), $margin, $color, $alpha); |
207
|
1 |
|
}); |
208
|
|
|
|
209
|
1 |
|
return $this; |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* @return string[] |
214
|
|
|
*/ |
215
|
1 |
|
private function getPath() |
216
|
|
|
{ |
217
|
1 |
|
$filename = basename($this->File->name); |
218
|
1 |
|
$p1 = StringHelper::byteSubstr($filename, 0, 2); |
219
|
1 |
|
$p2 = StringHelper::byteSubstr($filename, 2, 2); |
220
|
1 |
|
$p = DIRECTORY_SEPARATOR . $p1 . DIRECTORY_SEPARATOR . $p2; |
221
|
|
|
|
222
|
|
|
return [ |
223
|
1 |
|
Module::module()->storage_path . $p, |
224
|
1 |
|
Module::module()->storage_web_path . $p |
225
|
1 |
|
]; |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
/** |
229
|
|
|
* @param string $mark |
230
|
|
|
* @return string[] |
231
|
|
|
*/ |
232
|
1 |
|
private function getMarkedFilePath($mark) |
233
|
|
|
{ |
234
|
1 |
|
\Yii::trace('calculate mark file path', __METHOD__); |
235
|
|
|
|
236
|
1 |
|
$ext = pathinfo($this->File->name, PATHINFO_EXTENSION); |
237
|
|
|
|
238
|
1 |
|
list($path, $web_path) = $this->getPath(); |
239
|
1 |
|
$mark_file_path = $path . DIRECTORY_SEPARATOR . $mark . '.' . $ext; |
240
|
1 |
|
$mark_file_web_path = $web_path . '/' . $mark . '.' . $ext; |
241
|
|
|
|
242
|
1 |
|
return [$mark_file_path, $mark_file_web_path]; |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
/** |
246
|
|
|
* @param \Imagine\Image\ImageInterface $Image |
247
|
|
|
* @param string $mark |
248
|
|
|
*/ |
249
|
1 |
|
private function createMarkedFile(ImageInterface $Image, $mark) |
250
|
|
|
{ |
251
|
1 |
|
\Yii::beginProfile('create cache file:' . $this->File->id, __METHOD__); |
252
|
|
|
|
253
|
1 |
|
list($mark_file_path, $mark_file_web_path) = $this->getMarkedFilePath($mark); |
|
|
|
|
254
|
|
|
|
255
|
1 |
|
$mark_dir_path = dirname($mark_file_path); |
256
|
1 |
|
if (!file_exists($mark_dir_path) || !is_dir($mark_dir_path)) { |
257
|
1 |
|
FileHelper::createDirectory($mark_dir_path); |
258
|
1 |
|
} |
259
|
|
|
|
260
|
1 |
|
$Image->save($mark_file_path, ['quality' => 90]); |
261
|
1 |
|
@chmod($mark_file_path, 0664); |
|
|
|
|
262
|
|
|
|
263
|
1 |
|
\Yii::endProfile('create cache file:' . $this->File->id, __METHOD__); |
264
|
1 |
|
} |
265
|
|
|
|
266
|
|
|
|
267
|
|
|
/** |
268
|
|
|
* @param string $method |
269
|
|
|
* @param array $data |
270
|
|
|
*/ |
271
|
1 |
|
private function mark($method, array $data) |
|
|
|
|
272
|
|
|
{ |
273
|
1 |
|
$this->mark = func_get_args(); |
274
|
1 |
|
} |
275
|
|
|
|
276
|
|
|
/** |
277
|
|
|
* @return string |
278
|
|
|
*/ |
279
|
1 |
|
private function calculateMark() |
280
|
|
|
{ |
281
|
1 |
|
return sha1(Json::encode($this->mark)); |
282
|
|
|
} |
283
|
|
|
} |
This class, trait or interface 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 type will be removed from the class and what other constant to use instead.