1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace XoopsModules\Smallworld\Common; |
4
|
|
|
|
5
|
|
|
/* |
6
|
|
|
You may not change or alter any portion of this comment or credits |
7
|
|
|
of supporting developers from this source code or any supporting source code |
8
|
|
|
which is considered copyrighted (c) material of the original comment or credit authors. |
9
|
|
|
|
10
|
|
|
This program is distributed in the hope that it will be useful, |
11
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
12
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
13
|
|
|
*/ |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Image resizer class for xoops |
17
|
|
|
* |
18
|
|
|
* @copyright 2000-2020 XOOPS Project (https://xoops.org) |
19
|
|
|
* @license GPL 2.0 or later |
20
|
|
|
* @package XOOPS common |
21
|
|
|
* @since 1.0 |
22
|
|
|
* @min_xoops 2.5.9 |
23
|
|
|
* @author Goffy - Wedega - Email:<[email protected]> - Website:<https://wedega.com> |
24
|
|
|
*/ |
25
|
|
|
class Resizer |
26
|
|
|
{ |
27
|
|
|
public $sourceFile = ''; |
28
|
|
|
public $endFile = ''; |
29
|
|
|
public $maxWidth = 0; |
30
|
|
|
public $maxHeight = 0; |
31
|
|
|
public $imageMimetype = ''; |
32
|
|
|
public $jpgQuality = 90; |
33
|
|
|
public $mergeType = 0; |
34
|
|
|
public $mergePos = 0; |
35
|
|
|
public $degrees = 0; |
36
|
|
|
public $error = ''; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* resize image if size exceed given width/height |
40
|
|
|
* @return string|bool |
41
|
|
|
*/ |
42
|
|
|
public function resizeImage() |
43
|
|
|
{ |
44
|
|
|
// check file extension |
45
|
|
|
switch ($this->imageMimetype) { |
46
|
|
|
case'image/png': |
47
|
|
|
$img = imagecreatefrompng($this->sourceFile); |
48
|
|
|
break; |
49
|
|
|
case'image/jpeg': |
50
|
|
|
$img = imagecreatefromjpeg($this->sourceFile); |
51
|
|
|
if (!$img) { |
52
|
|
|
$img = imagecreatefromstring(file_get_contents($this->sourceFile)); |
53
|
|
|
} |
54
|
|
|
break; |
55
|
|
|
case'image/gif': |
56
|
|
|
$img = imagecreatefromgif($this->sourceFile); |
57
|
|
|
break; |
58
|
|
|
default: |
59
|
|
|
return 'Unsupported format'; |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
$width = imagesx($img); |
63
|
|
|
$height = imagesy($img); |
64
|
|
|
|
65
|
|
|
if ($width > $this->maxWidth || $height > $this->maxHeight) { |
66
|
|
|
// recalc image size based on this->maxWidth/this->maxHeight |
67
|
|
|
if ($width > $height) { |
68
|
|
|
if ($width < $this->maxWidth) { |
69
|
|
|
$new_width = $width; |
70
|
|
View Code Duplication |
} else { |
|
|
|
|
71
|
|
|
$new_width = $this->maxWidth; |
72
|
|
|
$divisor = $width / $new_width; |
73
|
|
|
$new_height = floor($height / $divisor); |
74
|
|
|
} |
75
|
|
|
} elseif ($height < $this->maxHeight) { |
76
|
|
|
$new_height = $height; |
77
|
|
View Code Duplication |
} else { |
|
|
|
|
78
|
|
|
$new_height = $this->maxHeight; |
79
|
|
|
$divisor = $height / $new_height; |
80
|
|
|
$new_width = floor($width / $divisor); |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
// Create a new temporary image. |
84
|
|
|
$tmpimg = imagecreatetruecolor($new_width, $new_height); |
|
|
|
|
85
|
|
|
imagealphablending($tmpimg, false); |
86
|
|
|
imagesavealpha($tmpimg, true); |
87
|
|
|
|
88
|
|
|
// Copy and resize old image into new image. |
89
|
|
|
imagecopyresampled($tmpimg, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height); |
90
|
|
|
|
91
|
|
|
unlink($this->endFile); |
92
|
|
|
//compressing the file |
93
|
|
|
switch ($this->imageMimetype) { |
94
|
|
|
case'image/png': |
95
|
|
|
imagepng($tmpimg, $this->endFile, 0); |
96
|
|
|
break; |
97
|
|
|
case'image/jpeg': |
98
|
|
|
imagejpeg($tmpimg, $this->endFile, 100); |
99
|
|
|
break; |
100
|
|
|
case'image/gif': |
101
|
|
|
imagegif($tmpimg, $this->endFile); |
102
|
|
|
break; |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
// release the memory |
106
|
|
|
imagedestroy($tmpimg); |
107
|
|
|
} else { |
108
|
|
|
return 'copy'; |
109
|
|
|
} |
110
|
|
|
imagedestroy($img); |
111
|
|
|
|
112
|
|
|
return true; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* @return bool|string |
117
|
|
|
*/ |
118
|
|
|
public function resizeAndCrop() |
119
|
|
|
{ |
120
|
|
|
// check file extension |
121
|
|
View Code Duplication |
switch ($this->imageMimetype) { |
|
|
|
|
122
|
|
|
case 'image/png': |
123
|
|
|
$original = imagecreatefrompng($this->sourceFile); |
124
|
|
|
break; |
125
|
|
|
case 'image/jpeg': |
126
|
|
|
$original = imagecreatefromjpeg($this->sourceFile); |
127
|
|
|
break; |
128
|
|
|
case 'image/gif': |
129
|
|
|
$original = imagecreatefromgif($this->sourceFile); |
130
|
|
|
break; |
131
|
|
|
default: |
132
|
|
|
return 'Unsupported format'; |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
if (!$original) { |
136
|
|
|
return false; |
137
|
|
|
} |
138
|
|
|
// GET ORIGINAL IMAGE DIMENSIONS |
139
|
|
|
list($original_w, $original_h) = getimagesize($this->sourceFile); |
140
|
|
|
|
141
|
|
|
// RESIZE IMAGE AND PRESERVE PROPORTIONS |
142
|
|
|
$max_width_resize = $this->maxWidth; |
143
|
|
|
$max_height_resize = $this->maxHeight; |
144
|
|
|
if ($original_w > $original_h) { |
145
|
|
|
$max_height_ratio = $this->maxHeight / $original_h; |
146
|
|
|
$max_width_resize = (int)round($original_w * $max_height_ratio); |
147
|
|
|
} else { |
148
|
|
|
$max_width_ratio = $this->maxWidth / $original_w; |
149
|
|
|
$max_height_resize = (int)round($original_h * $max_width_ratio); |
150
|
|
|
} |
151
|
|
|
if ($max_width_resize < $this->maxWidth) { |
152
|
|
|
$max_height_ratio = $this->maxWidth / $max_width_resize; |
153
|
|
|
$max_height_resize = (int)round($this->maxHeight * $max_height_ratio); |
154
|
|
|
$max_width_resize = $this->maxWidth; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
// CREATE THE PROPORTIONAL IMAGE RESOURCE |
158
|
|
|
$thumb = imagecreatetruecolor($max_width_resize, $max_height_resize); |
159
|
|
|
if (!imagecopyresampled($thumb, $original, 0, 0, 0, 0, $max_width_resize, $max_height_resize, $original_w, $original_h)) { |
160
|
|
|
return false; |
161
|
|
|
} |
162
|
|
|
// CREATE THE CENTERED CROPPED IMAGE TO THE SPECIFIED DIMENSIONS |
163
|
|
|
$final = imagecreatetruecolor($this->maxWidth, $this->maxHeight); |
164
|
|
|
|
165
|
|
|
$max_width_offset = 0; |
166
|
|
|
$max_height_offset = 0; |
167
|
|
|
if ($this->maxWidth < $max_width_resize) { |
168
|
|
|
$max_width_offset = (int)round(($max_width_resize - $this->maxWidth) / 2); |
169
|
|
|
} else { |
170
|
|
|
$max_height_offset = (int)round(($max_height_resize - $this->maxHeight) / 2); |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
if (!imagecopy($final, $thumb, 0, 0, $max_width_offset, $max_height_offset, $max_width_resize, $max_height_resize)) { |
174
|
|
|
return false; |
175
|
|
|
} |
176
|
|
|
// STORE THE FINAL IMAGE - WILL OVERWRITE $this->endFile |
177
|
|
|
if (!imagejpeg($final, $this->endFile, $this->jpgQuality)) { |
178
|
|
|
return false; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
return true; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
public function mergeImage() |
185
|
|
|
{ |
186
|
|
|
$dest = imagecreatefromjpeg($this->endFile); |
187
|
|
|
$src = imagecreatefromjpeg($this->sourceFile); |
188
|
|
|
if (4 == $this->mergeType) { |
189
|
|
|
$imgWidth = (int)round($this->maxWidth / 2 - 1); |
190
|
|
|
$imgHeight = (int)round($this->maxHeight / 2 - 1); |
191
|
|
|
$posCol2 = (int)round($this->maxWidth / 2 + 1); |
192
|
|
|
$posRow2 = (int)round($this->maxHeight / 2 + 1); |
193
|
|
|
switch ($this->mergePos) { |
194
|
|
|
case 1: |
195
|
|
|
imagecopy($dest, $src, 0, 0, 0, 0, $imgWidth, $imgHeight); //top left |
196
|
|
|
break; |
197
|
|
|
case 2: |
198
|
|
|
imagecopy($dest, $src, $posCol2, 0, 0, 0, $imgWidth, $imgHeight); //top right |
199
|
|
|
break; |
200
|
|
|
case 3: |
201
|
|
|
imagecopy($dest, $src, 0, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom left |
202
|
|
|
break; |
203
|
|
|
case 4: |
204
|
|
|
imagecopy($dest, $src, $posCol2, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom right |
205
|
|
|
break; |
206
|
|
|
} |
207
|
|
|
} |
208
|
|
|
if (6 == $this->mergeType) { |
209
|
|
|
$imgWidth = (int)round($this->maxWidth / 3 - 1); |
210
|
|
|
$imgHeight = (int)round($this->maxHeight / 2 - 1); |
211
|
|
|
$posCol2 = (int)round($this->maxWidth / 3 + 1); |
212
|
|
|
$posCol3 = $posCol2 + (int)round($this->maxWidth / 3 + 1); |
213
|
|
|
$posRow2 = (int)round($this->maxHeight / 2 + 1); |
214
|
|
|
|
215
|
|
|
switch ($this->mergePos) { |
216
|
|
|
case 1: |
217
|
|
|
imagecopy($dest, $src, 0, 0, 0, 0, $imgWidth, $imgHeight); //top left |
218
|
|
|
break; |
219
|
|
|
case 2: |
220
|
|
|
imagecopy($dest, $src, $posCol2, 0, 0, 0, $imgWidth, $imgHeight); //top center |
221
|
|
|
break; |
222
|
|
|
case 3: |
223
|
|
|
imagecopy($dest, $src, $posCol3, 0, 0, 0, $imgWidth, $imgHeight); //top right |
224
|
|
|
break; |
225
|
|
|
case 4: |
226
|
|
|
imagecopy($dest, $src, 0, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom left |
227
|
|
|
break; |
228
|
|
|
case 5: |
229
|
|
|
imagecopy($dest, $src, $posCol2, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom center |
230
|
|
|
break; |
231
|
|
|
case 6: |
232
|
|
|
imagecopy($dest, $src, $posCol3, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom right |
233
|
|
|
break; |
234
|
|
|
} |
235
|
|
|
} |
236
|
|
|
imagejpeg($dest, $this->endFile); |
237
|
|
|
|
238
|
|
|
imagedestroy($src); |
239
|
|
|
imagedestroy($dest); |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
/** |
243
|
|
|
* @return bool|string |
244
|
|
|
*/ |
245
|
|
|
public function rotateImage() |
246
|
|
|
{ |
247
|
|
|
// check file extension |
248
|
|
View Code Duplication |
switch ($this->imageMimetype) { |
|
|
|
|
249
|
|
|
case 'image/png': |
250
|
|
|
$original = imagecreatefrompng($this->sourceFile); |
251
|
|
|
break; |
252
|
|
|
case 'image/jpeg': |
253
|
|
|
$original = imagecreatefromjpeg($this->sourceFile); |
254
|
|
|
break; |
255
|
|
|
case 'image/gif': |
256
|
|
|
$original = imagecreatefromgif($this->sourceFile); |
257
|
|
|
break; |
258
|
|
|
default: |
259
|
|
|
return 'Unsupported format'; |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
if (!$original) { |
263
|
|
|
return false; |
264
|
|
|
} |
265
|
|
|
// Rotate |
266
|
|
|
$tmpimg = imagerotate($original, $this->degrees, 0); |
267
|
|
|
|
268
|
|
|
unlink($this->endFile); |
269
|
|
|
//compressing the file |
270
|
|
|
switch ($this->imageMimetype) { |
271
|
|
|
case 'image/png': |
272
|
|
|
if (!imagepng($tmpimg, $this->endFile, 0)) { |
273
|
|
|
return false; |
274
|
|
|
} |
275
|
|
|
break; |
276
|
|
|
case 'image/jpeg': |
277
|
|
|
if (!imagejpeg($tmpimg, $this->endFile, $this->jpgQuality)) { |
278
|
|
|
return false; |
279
|
|
|
} |
280
|
|
|
break; |
281
|
|
|
case 'image/gif': |
282
|
|
|
if (!imagegif($tmpimg, $this->endFile)) { |
283
|
|
|
return false; |
284
|
|
|
} |
285
|
|
|
break; |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
// release the memory |
289
|
|
|
imagedestroy($tmpimg); |
290
|
|
|
|
291
|
|
|
return true; |
292
|
|
|
} |
293
|
|
|
} |
294
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.