source: trunk/www.guidonia.net/wp/wp-content/plugins/ferdinand-wordbook/phpthumb/phpthumb.filters.php@ 44

Last change on this file since 44 was 44, checked in by luciano, 14 years ago
File size: 67.0 KB
Line 
1<?php
2//////////////////////////////////////////////////////////////
3/// phpThumb() by James Heinrich <info@silisoftware.com> //
4// available at http://phpthumb.sourceforge.net ///
5//////////////////////////////////////////////////////////////
6/// //
7// phpthumb.filters.php - image processing filter functions //
8// ///
9//////////////////////////////////////////////////////////////
10
11class phpthumb_filters {
12
13 var $phpThumbObject = null;
14
15 function phpthumb_filters() {
16 return true;
17 }
18
19 function ApplyMask(&$gdimg_mask, &$gdimg_image) {
20 if (phpthumb_functions::gd_version() < 2) {
21 $this->DebugMessage('Skipping ApplyMask() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
22 return false;
23 }
24 if (phpthumb_functions::version_compare_replacement(phpversion(), '4.3.2', '>=')) {
25
26 $this->DebugMessage('Using alpha ApplyMask() technique', __FILE__, __LINE__);
27 if ($gdimg_mask_resized = phpthumb_functions::ImageCreateFunction(ImageSX($gdimg_image), ImageSY($gdimg_image))) {
28
29 ImageCopyResampled($gdimg_mask_resized, $gdimg_mask, 0, 0, 0, 0, ImageSX($gdimg_image), ImageSY($gdimg_image), ImageSX($gdimg_mask), ImageSY($gdimg_mask));
30 if ($gdimg_mask_blendtemp = phpthumb_functions::ImageCreateFunction(ImageSX($gdimg_image), ImageSY($gdimg_image))) {
31
32 $color_background = ImageColorAllocate($gdimg_mask_blendtemp, 0, 0, 0);
33 ImageFilledRectangle($gdimg_mask_blendtemp, 0, 0, ImageSX($gdimg_mask_blendtemp), ImageSY($gdimg_mask_blendtemp), $color_background);
34 ImageAlphaBlending($gdimg_mask_blendtemp, false);
35 ImageSaveAlpha($gdimg_mask_blendtemp, true);
36 for ($x = 0; $x < ImageSX($gdimg_image); $x++) {
37 for ($y = 0; $y < ImageSY($gdimg_image); $y++) {
38 //$RealPixel = phpthumb_functions::GetPixelColor($gdimg_mask_blendtemp, $x, $y);
39 $RealPixel = phpthumb_functions::GetPixelColor($gdimg_image, $x, $y);
40 $MaskPixel = phpthumb_functions::GrayscalePixel(phpthumb_functions::GetPixelColor($gdimg_mask_resized, $x, $y));
41 $MaskAlpha = 127 - (floor($MaskPixel['red'] / 2) * (1 - ($RealPixel['alpha'] / 127)));
42 $newcolor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_mask_blendtemp, $RealPixel['red'], $RealPixel['green'], $RealPixel['blue'], $MaskAlpha);
43 ImageSetPixel($gdimg_mask_blendtemp, $x, $y, $newcolor);
44 }
45 }
46 ImageAlphaBlending($gdimg_image, false);
47 ImageSaveAlpha($gdimg_image, true);
48 ImageCopy($gdimg_image, $gdimg_mask_blendtemp, 0, 0, 0, 0, ImageSX($gdimg_mask_blendtemp), ImageSY($gdimg_mask_blendtemp));
49 ImageDestroy($gdimg_mask_blendtemp);
50
51 } else {
52 $this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
53 }
54 ImageDestroy($gdimg_mask_resized);
55
56 } else {
57 $this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
58 }
59
60 } else {
61 // alpha merging requires PHP v4.3.2+
62 $this->DebugMessage('Skipping ApplyMask() technique because PHP is v"'.phpversion().'"', __FILE__, __LINE__);
63 }
64 return true;
65 }
66
67
68 function Bevel(&$gdimg, $width, $hexcolor1, $hexcolor2) {
69 $width = ($width ? $width : 5);
70 $hexcolor1 = ($hexcolor1 ? $hexcolor1 : 'FFFFFF');
71 $hexcolor2 = ($hexcolor2 ? $hexcolor2 : '000000');
72
73 ImageAlphaBlending($gdimg, true);
74 for ($i = 0; $i < $width; $i++) {
75 $alpha = round(($i / $width) * 127);
76 $color1 = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor1, false, $alpha);
77 $color2 = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor2, false, $alpha);
78
79 ImageLine($gdimg, $i, $i + 1, $i, ImageSY($gdimg) - $i - 1, $color1); // left
80 ImageLine($gdimg, $i, $i , ImageSX($gdimg) - $i, $i , $color1); // top
81 ImageLine($gdimg, ImageSX($gdimg) - $i, ImageSY($gdimg) - $i - 1, ImageSX($gdimg) - $i, $i + 1, $color2); // right
82 ImageLine($gdimg, ImageSX($gdimg) - $i, ImageSY($gdimg) - $i , $i, ImageSY($gdimg) - $i , $color2); // bottom
83 }
84 return true;
85 }
86
87
88 function Blur(&$gdimg, $radius=0.5) {
89 // Taken from Torstein Hønsi's phpUnsharpMask (see phpthumb.unsharp.php)
90
91 $radius = round(max(0, min($radius, 50)) * 2);
92 if (!$radius) {
93 return false;
94 }
95
96 $w = ImageSX($gdimg);
97 $h = ImageSY($gdimg);
98 if ($imgBlur = ImageCreateTrueColor($w, $h)) {
99 // Gaussian blur matrix:
100 // 1 2 1
101 // 2 4 2
102 // 1 2 1
103
104 // Move copies of the image around one pixel at the time and merge them with weight
105 // according to the matrix. The same matrix is simply repeated for higher radii.
106 for ($i = 0; $i < $radius; $i++) {
107 ImageCopy ($imgBlur, $gdimg, 0, 0, 1, 1, $w - 1, $h - 1); // up left
108 ImageCopyMerge($imgBlur, $gdimg, 1, 1, 0, 0, $w, $h, 50.00000); // down right
109 ImageCopyMerge($imgBlur, $gdimg, 0, 1, 1, 0, $w - 1, $h, 33.33333); // down left
110 ImageCopyMerge($imgBlur, $gdimg, 1, 0, 0, 1, $w, $h - 1, 25.00000); // up right
111 ImageCopyMerge($imgBlur, $gdimg, 0, 0, 1, 0, $w - 1, $h, 33.33333); // left
112 ImageCopyMerge($imgBlur, $gdimg, 1, 0, 0, 0, $w, $h, 25.00000); // right
113 ImageCopyMerge($imgBlur, $gdimg, 0, 0, 0, 1, $w, $h - 1, 20.00000); // up
114 ImageCopyMerge($imgBlur, $gdimg, 0, 1, 0, 0, $w, $h, 16.666667); // down
115 ImageCopyMerge($imgBlur, $gdimg, 0, 0, 0, 0, $w, $h, 50.000000); // center
116 ImageCopy ($gdimg, $imgBlur, 0, 0, 0, 0, $w, $h);
117 }
118 return true;
119 }
120 return false;
121 }
122
123
124 function BlurGaussian(&$gdimg) {
125 if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
126 if (ImageFilter($gdimg, IMG_FILTER_GAUSSIAN_BLUR)) {
127 return true;
128 }
129 $this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_GAUSSIAN_BLUR)', __FILE__, __LINE__);
130 // fall through and try it the hard way
131 }
132 $this->DebugMessage('FAILED: phpthumb_filters::BlurGaussian($gdimg) [using phpthumb_filters::Blur() instead]', __FILE__, __LINE__);
133 return phpthumb_filters::Blur($gdimg, 0.5);
134 }
135
136
137 function BlurSelective(&$gdimg) {
138 if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
139 if (ImageFilter($gdimg, IMG_FILTER_SELECTIVE_BLUR)) {
140 return true;
141 }
142 $this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_SELECTIVE_BLUR)', __FILE__, __LINE__);
143 // fall through and try it the hard way
144 }
145 // currently not implemented "the hard way"
146 $this->DebugMessage('FAILED: phpthumb_filters::BlurSelective($gdimg) [function not implemented]', __FILE__, __LINE__);
147 return false;
148 }
149
150
151 function Brightness(&$gdimg, $amount=0) {
152 if ($amount == 0) {
153 return true;
154 }
155 $amount = max(-255, min(255, $amount));
156
157 if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
158 if (ImageFilter($gdimg, IMG_FILTER_BRIGHTNESS, $amount)) {
159 return true;
160 }
161 $this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_BRIGHTNESS, '.$amount.')', __FILE__, __LINE__);
162 // fall through and try it the hard way
163 }
164
165 $scaling = (255 - abs($amount)) / 255;
166 $baseamount = (($amount > 0) ? $amount : 0);
167 for ($x = 0; $x < ImageSX($gdimg); $x++) {
168 for ($y = 0; $y < ImageSY($gdimg); $y++) {
169 $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
170 foreach ($OriginalPixel as $key => $value) {
171 $NewPixel[$key] = round($baseamount + ($OriginalPixel[$key] * $scaling));
172 }
173 $newColor = ImageColorAllocate($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue']);
174 ImageSetPixel($gdimg, $x, $y, $newColor);
175 }
176 }
177 return true;
178 }
179
180
181 function Contrast(&$gdimg, $amount=0) {
182 if ($amount == 0) {
183 return true;
184 }
185 $amount = max(-255, min(255, $amount));
186
187 if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
188 // ImageFilter(IMG_FILTER_CONTRAST) has range +100 to -100 (positive numbers make it darker!)
189 $amount = ($amount / 255) * -100;
190 if (ImageFilter($gdimg, IMG_FILTER_CONTRAST, $amount)) {
191 return true;
192 }
193 $this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_CONTRAST, '.$amount.')', __FILE__, __LINE__);
194 // fall through and try it the hard way
195 }
196
197 if ($amount > 0) {
198 $scaling = 1 + ($amount / 255);
199 } else {
200 $scaling = (255 - abs($amount)) / 255;
201 }
202 for ($x = 0; $x < ImageSX($gdimg); $x++) {
203 for ($y = 0; $y < ImageSY($gdimg); $y++) {
204 $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
205 foreach ($OriginalPixel as $key => $value) {
206 $NewPixel[$key] = min(255, max(0, round($OriginalPixel[$key] * $scaling)));
207 }
208 $newColor = ImageColorAllocate($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue']);
209 ImageSetPixel($gdimg, $x, $y, $newColor);
210 }
211 }
212 }
213
214
215 function Colorize(&$gdimg, $amount, $targetColor) {
216 $amount = (is_numeric($amount) ? $amount : 25);
217 $amountPct = $amount / 100;
218 $targetColor = (phpthumb_functions::IsHexColor($targetColor) ? $targetColor : 'gray');
219
220 if ($amount == 0) {
221 return true;
222 }
223
224 if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
225 if ($targetColor == 'gray') {
226 $targetColor = '808080';
227 }
228 $r = round($amountPct * hexdec(substr($targetColor, 0, 2)));
229 $g = round($amountPct * hexdec(substr($targetColor, 2, 2)));
230 $b = round($amountPct * hexdec(substr($targetColor, 4, 2)));
231 if (ImageFilter($gdimg, IMG_FILTER_COLORIZE, $r, $g, $b)) {
232 return true;
233 }
234 $this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_COLORIZE)', __FILE__, __LINE__);
235 // fall through and try it the hard way
236 }
237
238 // overridden below for grayscale
239 if ($targetColor != 'gray') {
240 $TargetPixel['red'] = hexdec(substr($targetColor, 0, 2));
241 $TargetPixel['green'] = hexdec(substr($targetColor, 2, 2));
242 $TargetPixel['blue'] = hexdec(substr($targetColor, 4, 2));
243 }
244
245 for ($x = 0; $x < ImageSX($gdimg); $x++) {
246 for ($y = 0; $y < ImageSY($gdimg); $y++) {
247 $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
248 if ($targetColor == 'gray') {
249 $TargetPixel = phpthumb_functions::GrayscalePixel($OriginalPixel);
250 }
251 foreach ($TargetPixel as $key => $value) {
252 $NewPixel[$key] = round(max(0, min(255, ($OriginalPixel[$key] * ((100 - $amount) / 100)) + ($TargetPixel[$key] * $amountPct))));
253 }
254 //$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue'], $OriginalPixel['alpha']);
255 $newColor = ImageColorAllocate($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue']);
256 ImageSetPixel($gdimg, $x, $y, $newColor);
257 }
258 }
259 return true;
260 }
261
262
263 function Crop(&$gdimg, $left=0, $right=0, $top=0, $bottom=0) {
264 if (!$left && !$right && !$top && !$bottom) {
265 return true;
266 }
267 $oldW = ImageSX($gdimg);
268 $oldH = ImageSY($gdimg);
269 if (($left > 0) && ($left < 1)) { $left = round($left * $oldW); }
270 if (($right > 0) && ($right < 1)) { $right = round($right * $oldW); }
271 if (($top > 0) && ($top < 1)) { $top = round($top * $oldH); }
272 if (($bottom > 0) && ($bottom < 1)) { $bottom = round($bottom * $oldH); }
273 $right = min($oldW - $left - 1, $right);
274 $bottom = min($oldH - $top - 1, $bottom);
275 $newW = $oldW - $left - $right;
276 $newH = $oldH - $top - $bottom;
277
278 if ($imgCropped = ImageCreateTrueColor($newW, $newH)) {
279 ImageCopy($imgCropped, $gdimg, 0, 0, $left, $top, $newW, $newH);
280 if ($gdimg = ImageCreateTrueColor($newW, $newH)) {
281 ImageCopy($gdimg, $imgCropped, 0, 0, 0, 0, $newW, $newH);
282 ImageDestroy($imgCropped);
283 return true;
284 }
285 ImageDestroy($imgCropped);
286 }
287 return false;
288 }
289
290
291 function Desaturate(&$gdimg, $amount, $color='') {
292 if ($amount == 0) {
293 return true;
294 }
295 return phpthumb_filters::Colorize($gdimg, $amount, (phpthumb_functions::IsHexColor($color) ? $color : 'gray'));
296 }
297
298
299 function DropShadow(&$gdimg, $distance, $width, $hexcolor, $angle, $fade) {
300 if (phpthumb_functions::gd_version() < 2) {
301 return false;
302 }
303 $distance = ($distance ? $distance : 10);
304 $width = ($width ? $width : 10);
305 $hexcolor = ($hexcolor ? $hexcolor : '000000');
306 $angle = ($angle ? $angle : 225);
307 $fade = ($fade ? $fade : 1);
308
309 $width_shadow = cos(deg2rad($angle)) * ($distance + $width);
310 $height_shadow = sin(deg2rad($angle)) * ($distance + $width);
311
312 $scaling = min(ImageSX($gdimg) / (ImageSX($gdimg) + abs($width_shadow)), ImageSY($gdimg) / (ImageSY($gdimg) + abs($height_shadow)));
313
314 for ($i = 0; $i < $width; $i++) {
315 $WidthAlpha[$i] = (abs(($width / 2) - $i) / $width) * $fade;
316 $Offset['x'] = cos(deg2rad($angle)) * ($distance + $i);
317 $Offset['y'] = sin(deg2rad($angle)) * ($distance + $i);
318 }
319
320 $tempImageWidth = ImageSX($gdimg) + abs($Offset['x']);
321 $tempImageHeight = ImageSY($gdimg) + abs($Offset['y']);
322
323 if ($gdimg_dropshadow_temp = phpthumb_functions::ImageCreateFunction($tempImageWidth, $tempImageHeight)) {
324
325 ImageAlphaBlending($gdimg_dropshadow_temp, false);
326 ImageSaveAlpha($gdimg_dropshadow_temp, true);
327 $transparent1 = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_dropshadow_temp, 0, 0, 0, 127);
328 ImageFill($gdimg_dropshadow_temp, 0, 0, $transparent1);
329
330 for ($x = 0; $x < ImageSX($gdimg); $x++) {
331 for ($y = 0; $y < ImageSY($gdimg); $y++) {
332 $PixelMap[$x][$y] = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
333 }
334 }
335 for ($x = 0; $x < $tempImageWidth; $x++) {
336 for ($y = 0; $y < $tempImageHeight; $y++) {
337 //for ($i = 0; $i < $width; $i++) {
338 for ($i = 0; $i < 1; $i++) {
339 if (!isset($PixelMap[$x][$y]['alpha']) || ($PixelMap[$x][$y]['alpha'] > 0)) {
340 if (isset($PixelMap[$x + $Offset['x']][$y + $Offset['y']]['alpha']) && ($PixelMap[$x + $Offset['x']][$y + $Offset['y']]['alpha'] < 127)) {
341 $thisColor = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor, false, $PixelMap[$x + $Offset['x']][$y + $Offset['y']]['alpha']);
342 ImageSetPixel($gdimg_dropshadow_temp, $x, $y, $thisColor);
343 }
344 }
345 }
346 }
347 }
348
349 ImageAlphaBlending($gdimg_dropshadow_temp, true);
350 for ($x = 0; $x < ImageSX($gdimg); $x++) {
351 for ($y = 0; $y < ImageSY($gdimg); $y++) {
352 if ($PixelMap[$x][$y]['alpha'] < 127) {
353 $thisColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_dropshadow_temp, $PixelMap[$x][$y]['red'], $PixelMap[$x][$y]['green'], $PixelMap[$x][$y]['blue'], $PixelMap[$x][$y]['alpha']);
354 ImageSetPixel($gdimg_dropshadow_temp, $x, $y, $thisColor);
355 }
356 }
357 }
358
359 ImageSaveAlpha($gdimg, true);
360 ImageAlphaBlending($gdimg, false);
361 //$this->is_alpha = true;
362 $transparent2 = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 0, 0, 0, 127);
363 ImageFilledRectangle($gdimg, 0, 0, ImageSX($gdimg), ImageSY($gdimg), $transparent2);
364 ImageCopyResampled($gdimg, $gdimg_dropshadow_temp, 0, 0, 0, 0, ImageSX($gdimg), ImageSY($gdimg), ImageSX($gdimg_dropshadow_temp), ImageSY($gdimg_dropshadow_temp));
365
366 ImageDestroy($gdimg_dropshadow_temp);
367 }
368 return true;
369 }
370
371
372 function EdgeDetect(&$gdimg) {
373 if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
374 if (ImageFilter($gdimg, IMG_FILTER_EDGEDETECT)) {
375 return true;
376 }
377 $this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_EDGEDETECT)', __FILE__, __LINE__);
378 // fall through and try it the hard way
379 }
380 // currently not implemented "the hard way"
381 $this->DebugMessage('FAILED: phpthumb_filters::EdgeDetect($gdimg) [function not implemented]', __FILE__, __LINE__);
382 return false;
383 }
384
385
386 function Elipse($gdimg) {
387 if (phpthumb_functions::gd_version() < 2) {
388 return false;
389 }
390 // generate mask at twice desired resolution and downsample afterwards for easy antialiasing
391 if ($gdimg_elipsemask_double = phpthumb_functions::ImageCreateFunction(ImageSX($gdimg) * 2, ImageSY($gdimg) * 2)) {
392 if ($gdimg_elipsemask = phpthumb_functions::ImageCreateFunction(ImageSX($gdimg), ImageSY($gdimg))) {
393
394 $color_transparent = ImageColorAllocate($gdimg_elipsemask_double, 255, 255, 255);
395 ImageFilledEllipse($gdimg_elipsemask_double, ImageSX($gdimg), ImageSY($gdimg), (ImageSX($gdimg) - 1) * 2, (ImageSY($gdimg) - 1) * 2, $color_transparent);
396 ImageCopyResampled($gdimg_elipsemask, $gdimg_elipsemask_double, 0, 0, 0, 0, ImageSX($gdimg), ImageSY($gdimg), ImageSX($gdimg) * 2, ImageSY($gdimg) * 2);
397
398 phpthumb_filters::ApplyMask($gdimg_elipsemask, $gdimg);
399 ImageDestroy($gdimg_elipsemask);
400 return true;
401
402 } else {
403 $this->DebugMessage('$gdimg_elipsemask = phpthumb_functions::ImageCreateFunction() failed', __FILE__, __LINE__);
404 }
405 ImageDestroy($gdimg_elipsemask_double);
406 } else {
407 $this->DebugMessage('$gdimg_elipsemask_double = phpthumb_functions::ImageCreateFunction() failed', __FILE__, __LINE__);
408 }
409 return false;
410 }
411
412
413 function Emboss(&$gdimg) {
414 if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
415 if (ImageFilter($gdimg, IMG_FILTER_EMBOSS)) {
416 return true;
417 }
418 $this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_EMBOSS)', __FILE__, __LINE__);
419 // fall through and try it the hard way
420 }
421 // currently not implemented "the hard way"
422 $this->DebugMessage('FAILED: phpthumb_filters::Emboss($gdimg) [function not implemented]', __FILE__, __LINE__);
423 return false;
424 }
425
426
427 function Flip(&$gdimg, $x=false, $y=false) {
428 if (!$x && !$y) {
429 return false;
430 }
431 if ($tempImage = phpthumb_functions::ImageCreateFunction(ImageSX($gdimg), ImageSY($gdimg))) {
432 if ($x) {
433 ImageCopy($tempImage, $gdimg, 0, 0, 0, 0, ImageSX($gdimg), ImageSY($gdimg));
434 for ($x = 0; $x < ImageSX($gdimg); $x++) {
435 ImageCopy($gdimg, $tempImage, ImageSX($gdimg) - 1 - $x, 0, $x, 0, 1, ImageSY($gdimg));
436 }
437 }
438 if ($y) {
439 ImageCopy($tempImage, $gdimg, 0, 0, 0, 0, ImageSX($gdimg), ImageSY($gdimg));
440 for ($y = 0; $y < ImageSY($gdimg); $y++) {
441 ImageCopy($gdimg, $tempImage, 0, ImageSY($gdimg) - 1 - $y, 0, $y, ImageSX($gdimg), 1);
442 }
443 }
444 ImageDestroy($tempImage);
445 }
446 return true;
447 }
448
449
450 function Frame(&$gdimg, $frame_width, $edge_width, $hexcolor_frame, $hexcolor1, $hexcolor2) {
451 $frame_width = ($frame_width ? $frame_width : 5);
452 $edge_width = ($edge_width ? $edge_width : 1);
453 $hexcolor_frame = ($hexcolor_frame ? $hexcolor_frame : 'CCCCCC');
454 $hexcolor1 = ($hexcolor1 ? $hexcolor1 : 'FFFFFF');
455 $hexcolor2 = ($hexcolor2 ? $hexcolor2 : '000000');
456
457 $color_frame = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor_frame);
458 $color1 = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor1);
459 $color2 = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor2);
460 for ($i = 0; $i < $edge_width; $i++) {
461 // outer bevel
462 ImageLine($gdimg, $i, $i, $i, ImageSY($gdimg) - $i, $color1); // left
463 ImageLine($gdimg, $i, $i, ImageSX($gdimg) - $i, $i, $color1); // top
464 ImageLine($gdimg, ImageSX($gdimg) - $i, ImageSY($gdimg) - $i, ImageSX($gdimg) - $i, $i, $color2); // right
465 ImageLine($gdimg, ImageSX($gdimg) - $i, ImageSY($gdimg) - $i, $i, ImageSY($gdimg) - $i, $color2); // bottom
466 }
467 for ($i = 0; $i < $frame_width; $i++) {
468 // actual frame
469 ImageRectangle($gdimg, $edge_width + $i, $edge_width + $i, ImageSX($gdimg) - $edge_width - $i, ImageSY($gdimg) - $edge_width - $i, $color_frame);
470 }
471 for ($i = 0; $i < $edge_width; $i++) {
472 // inner bevel
473 ImageLine($gdimg, $frame_width + $edge_width + $i, $frame_width + $edge_width + $i, $frame_width + $edge_width + $i, ImageSY($gdimg) - $frame_width - $edge_width - $i, $color2); // left
474 ImageLine($gdimg, $frame_width + $edge_width + $i, $frame_width + $edge_width + $i, ImageSX($gdimg) - $frame_width - $edge_width - $i, $frame_width + $edge_width + $i, $color2); // top
475 ImageLine($gdimg, ImageSX($gdimg) - $frame_width - $edge_width - $i, ImageSY($gdimg) - $frame_width - $edge_width - $i, ImageSX($gdimg) - $frame_width - $edge_width - $i, $frame_width + $edge_width + $i, $color1); // right
476 ImageLine($gdimg, ImageSX($gdimg) - $frame_width - $edge_width - $i, ImageSY($gdimg) - $frame_width - $edge_width - $i, $frame_width + $edge_width + $i, ImageSY($gdimg) - $frame_width - $edge_width - $i, $color1); // bottom
477 }
478 return true;
479 }
480
481
482 function Gamma(&$gdimg, $amount) {
483 if (number_format($amount, 4) == '1.0000') {
484 return true;
485 }
486 return ImageGammaCorrect($gdimg, 1.0, $amount);
487 }
488
489
490 function Grayscale(&$gdimg) {
491 if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
492 if (ImageFilter($gdimg, IMG_FILTER_GRAYSCALE)) {
493 return true;
494 }
495 $this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_GRAYSCALE)', __FILE__, __LINE__);
496 // fall through and try it the hard way
497 }
498 return phpthumb_filters::Colorize($gdimg, 100, 'gray');
499 }
500
501
502 function HistogramAnalysis(&$gdimg, $calculateGray=false) {
503 $ImageSX = ImageSX($gdimg);
504 $ImageSY = ImageSY($gdimg);
505 for ($x = 0; $x < $ImageSX; $x++) {
506 for ($y = 0; $y < $ImageSY; $y++) {
507 $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
508 @$Analysis['red'][$OriginalPixel['red']]++;
509 @$Analysis['green'][$OriginalPixel['green']]++;
510 @$Analysis['blue'][$OriginalPixel['blue']]++;
511 @$Analysis['alpha'][$OriginalPixel['alpha']]++;
512 if ($calculateGray) {
513 $GrayPixel = phpthumb_functions::GrayscalePixel($OriginalPixel);
514 @$Analysis['gray'][$GrayPixel['red']]++;
515 }
516 }
517 }
518 $keys = array('red', 'green', 'blue', 'alpha');
519 if ($calculateGray) {
520 $keys[] = 'gray';
521 }
522 foreach ($keys as $dummy => $key) {
523 ksort($Analysis[$key]);
524 }
525 return $Analysis;
526 }
527
528
529 function HistogramStretch(&$gdimg, $band='*', $method=0, $threshold=0.1) {
530 // equivalent of "Auto Contrast" in Adobe Photoshop
531 // method 0 stretches according to RGB colors. Gives a more conservative stretch.
532 // method 1 band stretches according to grayscale which is color-biased (59% green, 30% red, 11% blue). May give a punchier / more aggressive stretch, possibly appearing over-saturated
533 $Analysis = phpthumb_filters::HistogramAnalysis($gdimg, true);
534 $keys = array('r'=>'red', 'g'=>'green', 'b'=>'blue', 'a'=>'alpha', '*'=>(($method == 0) ? 'all' : 'gray'));
535 $band = substr($band, 0, 1);
536 if (!isset($keys[$band])) {
537 return false;
538 }
539 $key = $keys[$band];
540
541 // If the absolute brightest and darkest pixels are used then one random
542 // pixel in the image could throw off the whole system. Instead, count up/down
543 // from the limit and allow <threshold> (default = 0.1%) of brightest/darkest
544 // pixels to be clipped to min/max
545 $threshold = floatval($threshold) / 100;
546 $clip_threshold = ImageSX($gdimg) * ImageSX($gdimg) * $threshold;
547 //if ($min >= 0) {
548 // $range_min = min($min, 255);
549 //} else {
550 $countsum = 0;
551 for ($i = 0; $i <= 255; $i++) {
552 if ($method == 0) {
553 $countsum = max(@$Analysis['red'][$i], @$Analysis['green'][$i], @$Analysis['blue'][$i]);
554 } else {
555 $countsum += @$Analysis[$key][$i];
556 }
557 if ($countsum >= $clip_threshold) {
558 $range_min = $i - 1;
559 break;
560 }
561 }
562 $range_min = max($range_min, 0);
563 //}
564 //if ($max > 0) {
565 // $range_max = max($max, 255);
566 //} else {
567 $countsum = 0;
568 for ($i = 255; $i >= 0; $i--) {
569 if ($method == 0) {
570 $countsum = max(@$Analysis['red'][$i], @$Analysis['green'][$i], @$Analysis['blue'][$i]);
571 } else {
572 $countsum += @$Analysis[$key][$i];
573 }
574 if ($countsum >= $clip_threshold) {
575 $range_max = $i + 1;
576 break;
577 }
578 }
579 $range_max = min($range_max, 255);
580 //}
581 $range_scale = (($range_max == $range_min) ? 1 : (255 / ($range_max - $range_min)));
582 if (($range_min == 0) && ($range_max == 255)) {
583 // no adjustment neccesary - don't waste CPU time!
584 return true;
585 }
586
587 $ImageSX = ImageSX($gdimg);
588 $ImageSY = ImageSY($gdimg);
589 for ($x = 0; $x < $ImageSX; $x++) {
590 for ($y = 0; $y < $ImageSY; $y++) {
591 $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
592 if ($band == '*') {
593 $new['red'] = min(255, max(0, ($OriginalPixel['red'] - $range_min) * $range_scale));
594 $new['green'] = min(255, max(0, ($OriginalPixel['green'] - $range_min) * $range_scale));
595 $new['blue'] = min(255, max(0, ($OriginalPixel['blue'] - $range_min) * $range_scale));
596 $new['alpha'] = min(255, max(0, ($OriginalPixel['alpha'] - $range_min) * $range_scale));
597 } else {
598 $new = $OriginalPixel;
599 $new[$key] = min(255, max(0, ($OriginalPixel[$key] - $range_min) * $range_scale));
600 }
601 $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, $new['red'], $new['green'], $new['blue'], $new['alpha']);
602 ImageSetPixel($gdimg, $x, $y, $newColor);
603 }
604 }
605
606 return true;
607 }
608
609
610 function HistogramOverlay(&$gdimg, $bands='*', $colors='', $width=0.25, $height=0.25, $alignment='BR', $opacity=50, $margin_x=5, $margin_y=null) {
611 $margin_y = (is_null($margin_y) ? $margin_x : $margin_y);
612
613 $Analysis = phpthumb_filters::HistogramAnalysis($gdimg, true);
614 $histW = round(($width > 1) ? min($width, ImageSX($gdimg)) : ImageSX($gdimg) * $width);
615 $histH = round(($width > 1) ? min($width, ImageSX($gdimg)) : ImageSX($gdimg) * $width);
616 if ($gdHist = ImageCreateTrueColor($histW, $histH)) {
617 $color_back = phpthumb_functions::ImageColorAllocateAlphaSafe($gdHist, 0, 0, 0, 127);
618 ImageFilledRectangle($gdHist, 0, 0, $histW, $histH, $color_back);
619 ImageAlphaBlending($gdHist, false);
620 ImageSaveAlpha($gdHist, true);
621
622 $HistogramTempWidth = 256;
623 $HistogramTempHeight = 100;
624 if ($gdHistTemp = ImageCreateTrueColor($HistogramTempWidth, $HistogramTempHeight)) {
625 $color_back_temp = phpthumb_functions::ImageColorAllocateAlphaSafe($gdHistTemp, 255, 0, 255, 127);
626 ImageAlphaBlending($gdHistTemp, false);
627 ImageSaveAlpha($gdHistTemp, true);
628 ImageFilledRectangle($gdHistTemp, 0, 0, ImageSX($gdHistTemp), ImageSY($gdHistTemp), $color_back_temp);
629
630 $DefaultColors = array('r'=>'FF0000', 'g'=>'00FF00', 'b'=>'0000FF', 'a'=>'999999', '*'=>'FFFFFF');
631 $Colors = explode(';', $colors);
632 $BandsToGraph = array_unique(preg_split('//', $bands));
633 $keys = array('r'=>'red', 'g'=>'green', 'b'=>'blue', 'a'=>'alpha', '*'=>'gray');
634 foreach ($BandsToGraph as $key => $band) {
635 if (!isset($keys[$band])) {
636 continue;
637 }
638 $PeakValue = max($Analysis[$keys[$band]]);
639 $thisColor = phpthumb_functions::ImageHexColorAllocate($gdHistTemp, phpthumb_functions::IsHexColor(@$Colors[$key]) ? $Colors[$key] : $DefaultColors[$band]);
640 for ($x = 0; $x < $HistogramTempWidth; $x++) {
641 ImageLine($gdHistTemp, $x, $HistogramTempHeight - 1, $x, $HistogramTempHeight - 1 - round(@$Analysis[$keys[$band]][$x] / $PeakValue * $HistogramTempHeight), $thisColor);
642 }
643 ImageLine($gdHistTemp, 0, $HistogramTempHeight - 1, $HistogramTempWidth - 1, $HistogramTempHeight - 1, $thisColor);
644 ImageLine($gdHistTemp, 0, $HistogramTempHeight - 2, $HistogramTempWidth - 1, $HistogramTempHeight - 2, $thisColor);
645 }
646 ImageCopyResampled($gdHist, $gdHistTemp, 0, 0, 0, 0, ImageSX($gdHist), ImageSY($gdHist), ImageSX($gdHistTemp), ImageSY($gdHistTemp));
647 ImageDestroy($gdHistTemp);
648 } else {
649 return false;
650 }
651
652 phpthumb_filters::WatermarkOverlay($gdimg, $gdHist, $alignment, $opacity, $margin_x, $margin_y);
653 ImageDestroy($gdHist);
654 return true;
655 }
656 return false;
657 }
658
659
660 function ImageBorder(&$gdimg, $border_width, $radius_x, $radius_y, $hexcolor_border) {
661 $border_width = ($border_width ? $border_width : 1);
662 $radius_x = ($radius_x ? $radius_x : 0);
663 $radius_y = ($radius_y ? $radius_y : 0);
664
665 $output_width = ImageSX($gdimg);
666 $output_height = ImageSY($gdimg);
667
668 list($new_width, $new_height) = phpthumb_functions::ProportionalResize($output_width, $output_height, $output_width - max($border_width * 2, $radius_x), $output_height - max($border_width * 2, $radius_y));
669 $offset_x = ($radius_x ? $output_width - $new_width - $radius_x : 0);
670 $offset_y = ($radius_y ? $output_height - $new_height - $radius_y : 0);
671
672//header('Content-Type: image/png');
673//ImagePNG($gdimg);
674//exit;
675 if ($gd_border_canvas = phpthumb_functions::ImageCreateFunction($output_width, $output_height)) {
676
677 ImageSaveAlpha($gd_border_canvas, true);
678 ImageAlphaBlending($gd_border_canvas, false);
679 $color_background = phpthumb_functions::ImageColorAllocateAlphaSafe($gd_border_canvas, 255, 255, 255, 127);
680 ImageFilledRectangle($gd_border_canvas, 0, 0, $output_width, $output_height, $color_background);
681
682 $color_border = phpthumb_functions::ImageHexColorAllocate($gd_border_canvas, (phpthumb_functions::IsHexColor($hexcolor_border) ? $hexcolor_border : '000000'));
683
684 for ($i = 0; $i < $border_width; $i++) {
685 ImageLine($gd_border_canvas, floor($offset_x / 2) + $radius_x, $i, $output_width - $radius_x - ceil($offset_x / 2), $i, $color_border); // top
686 ImageLine($gd_border_canvas, floor($offset_x / 2) + $radius_x, $output_height - 1 - $i, $output_width - $radius_x - ceil($offset_x / 2), $output_height - 1 - $i, $color_border); // bottom
687 ImageLine($gd_border_canvas, floor($offset_x / 2) + $i, $radius_y, floor($offset_x / 2) + $i, $output_height - $radius_y, $color_border); // left
688 ImageLine($gd_border_canvas, $output_width - 1 - $i - ceil($offset_x / 2), $radius_y, $output_width - 1 - $i - ceil($offset_x / 2), $output_height - $radius_y, $color_border); // right
689 }
690
691 if ($radius_x && $radius_y) {
692
693 // PHP bug: ImageArc() with thicknesses > 1 give bad/undesirable/unpredicatable results
694 // Solution: Draw multiple 1px arcs side-by-side.
695
696 // Problem: parallel arcs give strange/ugly antialiasing problems
697 // Solution: draw non-parallel arcs, from one side of the line thickness at the start angle
698 // to the opposite edge of the line thickness at the terminating angle
699 for ($thickness_offset = 0; $thickness_offset < $border_width; $thickness_offset++) {
700 ImageArc($gd_border_canvas, floor($offset_x / 2) + 1 + $radius_x, $thickness_offset - 1 + $radius_y, $radius_x * 2, $radius_y * 2, 180, 270, $color_border); // top-left
701 ImageArc($gd_border_canvas, $output_width - $radius_x - 1 - ceil($offset_x / 2), $thickness_offset - 1 + $radius_y, $radius_x * 2, $radius_y * 2, 270, 360, $color_border); // top-right
702 ImageArc($gd_border_canvas, $output_width - $radius_x - 1 - ceil($offset_x / 2), $output_height - $thickness_offset - $radius_y, $radius_x * 2, $radius_y * 2, 0, 90, $color_border); // bottom-right
703 ImageArc($gd_border_canvas, floor($offset_x / 2) + 1 + $radius_x, $output_height - $thickness_offset - $radius_y, $radius_x * 2, $radius_y * 2, 90, 180, $color_border); // bottom-left
704 }
705 if ($border_width > 1) {
706 for ($thickness_offset = 0; $thickness_offset < $border_width; $thickness_offset++) {
707 ImageArc($gd_border_canvas, floor($offset_x / 2) + $thickness_offset + $radius_x, $radius_y, $radius_x * 2, $radius_y * 2, 180, 270, $color_border); // top-left
708 ImageArc($gd_border_canvas, $output_width - $thickness_offset - $radius_x - 1 - ceil($offset_x / 2), $radius_y, $radius_x * 2, $radius_y * 2, 270, 360, $color_border); // top-right
709 ImageArc($gd_border_canvas, $output_width - $thickness_offset - $radius_x - 1 - ceil($offset_x / 2), $output_height - $radius_y, $radius_x * 2, $radius_y * 2, 0, 90, $color_border); // bottom-right
710 ImageArc($gd_border_canvas, floor($offset_x / 2) + $thickness_offset + $radius_x, $output_height - $radius_y, $radius_x * 2, $radius_y * 2, 90, 180, $color_border); // bottom-left
711 }
712 }
713
714 }
715 $this->phpThumbObject->ImageResizeFunction($gd_border_canvas, $gdimg, floor(($output_width - $new_width) / 2), round(($output_height - $new_height) / 2), 0, 0, $new_width, $new_height, $output_width, $output_height);
716
717 ImageDestroy($gdimg);
718 $gdimg = phpthumb_functions::ImageCreateFunction($output_width, $output_height);
719 ImageSaveAlpha($gdimg, true);
720 ImageAlphaBlending($gdimg, false);
721 $gdimg_color_background = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 255, 255, 255, 127);
722 ImageFilledRectangle($gdimg, 0, 0, $output_width, $output_height, $gdimg_color_background);
723
724 ImageCopy($gdimg, $gd_border_canvas, 0, 0, 0, 0, $output_width, $output_height);
725 //$gdimg = $gd_border_canvas;
726 ImageDestroy($gd_border_canvas);
727 return true;
728
729
730 } else {
731 $this->DebugMessage('FAILED: $gd_border_canvas = phpthumb_functions::ImageCreateFunction('.$output_width.', '.$output_height.')', __FILE__, __LINE__);
732 }
733 return false;
734 }
735
736
737 function ImprovedImageRotate(&$gdimg_source, $rotate_angle=0, $config_background_hexcolor='FFFFFF', $bg=null) {
738 while ($rotate_angle < 0) {
739 $rotate_angle += 360;
740 }
741 $rotate_angle = $rotate_angle % 360;
742 if ($rotate_angle != 0) {
743
744 $background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_source, $config_background_hexcolor);
745
746 if ((phpthumb_functions::gd_version() >= 2) && !$bg && ($rotate_angle % 90)) {
747
748 //$this->DebugMessage('Using alpha rotate', __FILE__, __LINE__);
749 if ($gdimg_rotate_mask = phpthumb_functions::ImageCreateFunction(ImageSX($gdimg_source), ImageSY($gdimg_source))) {
750
751 for ($i = 0; $i <= 255; $i++) {
752 $color_mask[$i] = ImageColorAllocate($gdimg_rotate_mask, $i, $i, $i);
753 }
754 ImageFilledRectangle($gdimg_rotate_mask, 0, 0, ImageSX($gdimg_rotate_mask), ImageSY($gdimg_rotate_mask), $color_mask[255]);
755 $imageX = ImageSX($gdimg_source);
756 $imageY = ImageSY($gdimg_source);
757 for ($x = 0; $x < $imageX; $x++) {
758 for ($y = 0; $y < $imageY; $y++) {
759 $pixelcolor = phpthumb_functions::GetPixelColor($gdimg_source, $x, $y);
760 ImageSetPixel($gdimg_rotate_mask, $x, $y, $color_mask[255 - round($pixelcolor['alpha'] * 255 / 127)]);
761 }
762 }
763 $gdimg_rotate_mask = ImageRotate($gdimg_rotate_mask, $rotate_angle, $color_mask[0]);
764 $gdimg_source = ImageRotate($gdimg_source, $rotate_angle, $background_color);
765
766 ImageAlphaBlending($gdimg_source, false);
767 ImageSaveAlpha($gdimg_source, true);
768 //$this->is_alpha = true;
769 $phpThumbFilters = new phpthumb_filters();
770 $phpThumbFilters->phpThumbObject = $this;
771 $phpThumbFilters->ApplyMask($gdimg_rotate_mask, $gdimg_source);
772
773 ImageDestroy($gdimg_rotate_mask);
774
775 } else {
776 //$this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
777 }
778
779 } else {
780
781 if (phpthumb_functions::gd_version() < 2) {
782 //$this->DebugMessage('Using non-alpha rotate because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
783 } elseif ($bg) {
784 //$this->DebugMessage('Using non-alpha rotate because $this->bg is "'.$bg.'"', __FILE__, __LINE__);
785 } elseif ($rotate_angle % 90) {
786 //$this->DebugMessage('Using non-alpha rotate because ($rotate_angle % 90) = "'.($rotate_angle % 90).'"', __FILE__, __LINE__);
787 } else {
788 //$this->DebugMessage('Using non-alpha rotate because $this->thumbnailFormat is "'.$this->thumbnailFormat.'"', __FILE__, __LINE__);
789 }
790
791 if (ImageColorTransparent($gdimg_source) >= 0) {
792 // ImageRotate() forgets all about an image's transparency and sets the transparent color to black
793 // To compensate, flood-fill the transparent color of the source image with the specified background color first
794 // then rotate and the colors should match
795
796 if (!function_exists('ImageIsTrueColor') || !ImageIsTrueColor($gdimg_source)) {
797 // convert paletted image to true-color before rotating to prevent nasty aliasing artifacts
798
799 //$this->source_width = ImageSX($gdimg_source);
800 //$this->source_height = ImageSY($gdimg_source);
801 $gdimg_newsrc = phpthumb_functions::ImageCreateFunction(ImageSX($gdimg_source), ImageSY($gdimg_source));
802 $background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_newsrc, $config_background_hexcolor);
803 ImageFilledRectangle($gdimg_newsrc, 0, 0, ImageSX($gdimg_source), ImageSY($gdimg_source), phpthumb_functions::ImageHexColorAllocate($gdimg_newsrc, $config_background_hexcolor));
804 ImageCopy($gdimg_newsrc, $gdimg_source, 0, 0, 0, 0, ImageSX($gdimg_source), ImageSY($gdimg_source));
805 ImageDestroy($gdimg_source);
806 unset($gdimg_source);
807 $gdimg_source = $gdimg_newsrc;
808 unset($gdimg_newsrc);
809
810 } else {
811
812 ImageColorSet(
813 $gdimg_source,
814 ImageColorTransparent($gdimg_source),
815 hexdec(substr($config_background_hexcolor, 0, 2)),
816 hexdec(substr($config_background_hexcolor, 2, 2)),
817 hexdec(substr($config_background_hexcolor, 4, 2)));
818
819 ImageColorTransparent($gdimg_source, -1);
820
821 }
822 }
823
824 $gdimg_source = ImageRotate($gdimg_source, $rotate_angle, $background_color);
825
826 }
827 }
828 return true;
829 }
830
831
832 function MeanRemoval(&$gdimg) {
833 if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
834 if (ImageFilter($gdimg, IMG_FILTER_MEAN_REMOVAL)) {
835 return true;
836 }
837 $this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_MEAN_REMOVAL)', __FILE__, __LINE__);
838 // fall through and try it the hard way
839 }
840 // currently not implemented "the hard way"
841 $this->DebugMessage('FAILED: phpthumb_filters::MeanRemoval($gdimg) [function not implemented]', __FILE__, __LINE__);
842 return false;
843 }
844
845
846 function Negative(&$gdimg) {
847 if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
848 if (ImageFilter($gdimg, IMG_FILTER_NEGATE)) {
849 return true;
850 }
851 $this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_NEGATE)', __FILE__, __LINE__);
852 // fall through and try it the hard way
853 }
854 $ImageSX = ImageSX($gdimg);
855 $ImageSY = ImageSY($gdimg);
856 for ($x = 0; $x < $ImageSX; $x++) {
857 for ($y = 0; $y < $ImageSY; $y++) {
858 $currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
859 $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, (~$currentPixel['red'] & 0xFF), (~$currentPixel['green'] & 0xFF), (~$currentPixel['blue'] & 0xFF), $currentPixel['alpha']);
860 ImageSetPixel($gdimg, $x, $y, $newColor);
861 }
862 }
863 return true;
864 }
865
866
867 function RoundedImageCorners(&$gdimg, $radius_x, $radius_y) {
868 // generate mask at twice desired resolution and downsample afterwards for easy antialiasing
869 // mask is generated as a white double-size elipse on a triple-size black background and copy-paste-resampled
870 // onto a correct-size mask image as 4 corners due to errors when the entire mask is resampled at once (gray edges)
871 if ($gdimg_cornermask_triple = phpthumb_functions::ImageCreateFunction($radius_x * 6, $radius_y * 6)) {
872 if ($gdimg_cornermask = phpthumb_functions::ImageCreateFunction(ImageSX($gdimg), ImageSY($gdimg))) {
873
874 $color_transparent = ImageColorAllocate($gdimg_cornermask_triple, 255, 255, 255);
875 ImageFilledEllipse($gdimg_cornermask_triple, $radius_x * 3, $radius_y * 3, $radius_x * 4, $radius_y * 4, $color_transparent);
876
877 ImageFilledRectangle($gdimg_cornermask, 0, 0, ImageSX($gdimg), ImageSY($gdimg), $color_transparent);
878
879 ImageCopyResampled($gdimg_cornermask, $gdimg_cornermask_triple, 0, 0, $radius_x, $radius_y, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
880 ImageCopyResampled($gdimg_cornermask, $gdimg_cornermask_triple, 0, ImageSY($gdimg) - $radius_y, $radius_x, $radius_y * 3, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
881 ImageCopyResampled($gdimg_cornermask, $gdimg_cornermask_triple, ImageSX($gdimg) - $radius_x, ImageSY($gdimg) - $radius_y, $radius_x * 3, $radius_y * 3, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
882 ImageCopyResampled($gdimg_cornermask, $gdimg_cornermask_triple, ImageSX($gdimg) - $radius_x, 0, $radius_x * 3, $radius_y, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
883
884 phpthumb_filters::ApplyMask($gdimg_cornermask, $gdimg);
885 ImageDestroy($gdimg_cornermask);
886 $this->DebugMessage('RoundedImageCorners('.$radius_x.', '.$radius_y.') succeeded', __FILE__, __LINE__);
887 return true;
888
889 } else {
890 $this->DebugMessage('FAILED: $gdimg_cornermask = phpthumb_functions::ImageCreateFunction('.ImageSX($gdimg).', '.ImageSY($gdimg).')', __FILE__, __LINE__);
891 }
892 ImageDestroy($gdimg_cornermask_triple);
893
894 } else {
895 $this->DebugMessage('FAILED: $gdimg_cornermask_triple = phpthumb_functions::ImageCreateFunction('.($radius_x * 6).', '.($radius_y * 6).')', __FILE__, __LINE__);
896 }
897 return false;
898 }
899
900
901 function Saturation(&$gdimg, $amount, $color='') {
902 if ($amount == 0) {
903 return true;
904 } elseif ($amount > 0) {
905 $amount = 0 - $amount;
906 } else {
907 $amount = abs($amount);
908 }
909 return phpthumb_filters::Desaturate($gdimg, $amount, $color);
910 }
911
912
913 function Sepia(&$gdimg, $amount, $targetColor) {
914 $amount = (is_numeric($amount) ? max(0, min(100, $amount)) : 50);
915 $amountPct = $amount / 100;
916 $targetColor = (phpthumb_functions::IsHexColor($targetColor) ? $targetColor : 'A28065');
917
918 if ($amount == 0) {
919 return true;
920 }
921
922 if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
923 if (ImageFilter($gdimg, IMG_FILTER_GRAYSCALE)) {
924
925 $r = round($amountPct * hexdec(substr($targetColor, 0, 2)));
926 $g = round($amountPct * hexdec(substr($targetColor, 2, 2)));
927 $b = round($amountPct * hexdec(substr($targetColor, 4, 2)));
928 if (ImageFilter($gdimg, IMG_FILTER_COLORIZE, $r, $g, $b)) {
929 return true;
930 }
931 $this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_COLORIZE)', __FILE__, __LINE__);
932 // fall through and try it the hard way
933
934 } else {
935
936 $this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_GRAYSCALE)', __FILE__, __LINE__);
937 // fall through and try it the hard way
938
939 }
940 }
941
942 $TargetPixel['red'] = hexdec(substr($targetColor, 0, 2));
943 $TargetPixel['green'] = hexdec(substr($targetColor, 2, 2));
944 $TargetPixel['blue'] = hexdec(substr($targetColor, 4, 2));
945
946 $ImageSX = ImageSX($gdimg);
947 $ImageSY = ImageSY($gdimg);
948 for ($x = 0; $x < $ImageSX; $x++) {
949 for ($y = 0; $y < $ImageSY; $y++) {
950 $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
951 $GrayPixel = phpthumb_functions::GrayscalePixel($OriginalPixel);
952
953 // http://www.gimpguru.org/Tutorials/SepiaToning/
954 // "In the traditional sepia toning process, the tinting occurs most in
955 // the mid-tones: the lighter and darker areas appear to be closer to B&W."
956 $SepiaAmount = ((128 - abs($GrayPixel['red'] - 128)) / 128) * $amountPct;
957
958 foreach ($TargetPixel as $key => $value) {
959 $NewPixel[$key] = round(max(0, min(255, $GrayPixel[$key] * (1 - $SepiaAmount) + ($TargetPixel[$key] * $SepiaAmount))));
960 }
961 $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue'], $OriginalPixel['alpha']);
962 ImageSetPixel($gdimg, $x, $y, $newColor);
963 }
964 }
965 return true;
966 }
967
968
969 function Smooth(&$gdimg, $amount=6) {
970 $amount = min(25, max(0, $amount));
971 if ($amount == 0) {
972 return true;
973 }
974 if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
975 if (ImageFilter($gdimg, IMG_FILTER_SMOOTH, $amount)) {
976 return true;
977 }
978 $this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_SMOOTH, '.$amount.')', __FILE__, __LINE__);
979 // fall through and try it the hard way
980 }
981 // currently not implemented "the hard way"
982 $this->DebugMessage('FAILED: phpthumb_filters::Smooth($gdimg, '.$amount.') [function not implemented]', __FILE__, __LINE__);
983 return false;
984 }
985
986
987 function SourceTransparentColorMask(&$gdimg, $hexcolor, $min_limit=5, $max_limit=10) {
988 $width = ImageSX($gdimg);
989 $height = ImageSY($gdimg);
990 if ($gdimg_mask = ImageCreateTrueColor($width, $height)) {
991 $R = hexdec(substr($hexcolor, 0, 2));
992 $G = hexdec(substr($hexcolor, 2, 2));
993 $B = hexdec(substr($hexcolor, 4, 2));
994 $targetPixel = array('red'=>$R, 'green'=>$G, 'blue'=>$B);
995 $cutoffRange = $max_limit - $min_limit;
996 for ($x = 0; $x < $width; $x++) {
997 for ($y = 0; $y < $height; $y++) {
998 $currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
999 $colorDiff = phpthumb_functions::PixelColorDifferencePercent($currentPixel, $targetPixel);
1000 $grayLevel = min($cutoffRange, MAX(0, -$min_limit + $colorDiff)) * (255 / MAX(1, $cutoffRange));
1001 $newColor = ImageColorAllocate($gdimg_mask, $grayLevel, $grayLevel, $grayLevel);
1002 ImageSetPixel($gdimg_mask, $x, $y, $newColor);
1003 }
1004 }
1005 return $gdimg_mask;
1006 }
1007 return false;
1008 }
1009
1010
1011 function Threshold(&$gdimg, $cutoff) {
1012 $width = ImageSX($gdimg);
1013 $height = ImageSY($gdimg);
1014 $cutoff = min(255, max(0, ($cutoff ? $cutoff : 128)));
1015 for ($x = 0; $x < $width; $x++) {
1016 for ($y = 0; $y < $height; $y++) {
1017 $currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
1018 $grayPixel = phpthumb_functions::GrayscalePixel($currentPixel);
1019 if ($grayPixel['red'] < $cutoff) {
1020 $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 0x00, 0x00, 0x00, $currentPixel['alpha']);
1021 } else {
1022 $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 0xFF, 0xFF, 0xFF, $currentPixel['alpha']);
1023 }
1024 ImageSetPixel($gdimg, $x, $y, $newColor);
1025 }
1026 }
1027 return true;
1028 }
1029
1030
1031 function ImageTrueColorToPalette2(&$image, $dither, $ncolors) {
1032 // http://www.php.net/manual/en/function.imagetruecolortopalette.php
1033 // zmorris at zsculpt dot com (17-Aug-2004 06:58)
1034 $width = ImageSX($image);
1035 $height = ImageSY($image);
1036 $image_copy = ImageCreateTrueColor($width, $height);
1037 //ImageCopyMerge($image_copy, $image, 0, 0, 0, 0, $width, $height, 100);
1038 ImageCopy($image_copy, $image, 0, 0, 0, 0, $width, $height);
1039 ImageTrueColorToPalette($image, $dither, $ncolors);
1040 ImageColorMatch($image_copy, $image);
1041 ImageDestroy($image_copy);
1042 return true;
1043 }
1044
1045 function ReduceColorDepth(&$gdimg, $colors=256, $dither=true) {
1046 $colors = max(min($colors, 256), 2);
1047 // ImageTrueColorToPalette usually makes ugly colors, the replacement is a bit better
1048 //ImageTrueColorToPalette($gdimg, $dither, $colors);
1049 phpthumb_filters::ImageTrueColorToPalette2($gdimg, $dither, $colors);
1050 return true;
1051 }
1052
1053
1054 function WhiteBalance(&$gdimg, $targetColor='') {
1055 if (phpthumb_functions::IsHexColor($targetColor)) {
1056 $targetPixel = array(
1057 'red' => hexdec(substr($targetColor, 0, 2)),
1058 'green' => hexdec(substr($targetColor, 2, 2)),
1059 'blue' => hexdec(substr($targetColor, 4, 2))
1060 );
1061 } else {
1062 $Analysis = phpthumb_filters::HistogramAnalysis($gdimg, false);
1063 $targetPixel = array(
1064 'red' => max(array_keys($Analysis['red'])),
1065 'green' => max(array_keys($Analysis['green'])),
1066 'blue' => max(array_keys($Analysis['blue']))
1067 );
1068 }
1069 $grayValue = phpthumb_functions::GrayscaleValue($targetPixel['red'], $targetPixel['green'], $targetPixel['blue']);
1070 $scaleR = $grayValue / $targetPixel['red'];
1071 $scaleG = $grayValue / $targetPixel['green'];
1072 $scaleB = $grayValue / $targetPixel['blue'];
1073
1074 for ($x = 0; $x < ImageSX($gdimg); $x++) {
1075 for ($y = 0; $y < ImageSY($gdimg); $y++) {
1076 $currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
1077 $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe(
1078 $gdimg,
1079 max(0, min(255, round($currentPixel['red'] * $scaleR))),
1080 max(0, min(255, round($currentPixel['green'] * $scaleG))),
1081 max(0, min(255, round($currentPixel['blue'] * $scaleB))),
1082 $currentPixel['alpha']
1083 );
1084 ImageSetPixel($gdimg, $x, $y, $newColor);
1085 }
1086 }
1087 return true;
1088 }
1089
1090
1091 function WatermarkText(&$gdimg, $text, $size, $alignment, $hex_color='000000', $ttffont='', $opacity=100, $margin=5, $angle=0, $bg_color=false, $bg_opacity=0, $fillextend='') {
1092 // text watermark requested
1093 if (!$text) {
1094 return false;
1095 }
1096 ImageAlphaBlending($gdimg, true);
1097
1098 if (eregi('^([0-9\\.\\-]*)x([0-9\\.\\-]*)(@[LCR])?$', $alignment, $matches)) {
1099 $originOffsetX = intval($matches[1]);
1100 $originOffsetY = intval($matches[2]);
1101 $alignment = (@$matches[4] ? $matches[4] : 'L');
1102 $margin = 0;
1103 } else {
1104 $originOffsetX = 0;
1105 $originOffsetY = 0;
1106 }
1107
1108 $metaTextArray = array(
1109 '^Fb' => $this->phpThumbObject->getimagesizeinfo['filesize'],
1110 '^Fk' => round($this->phpThumbObject->getimagesizeinfo['filesize'] / 1024),
1111 '^Fm' => round($this->phpThumbObject->getimagesizeinfo['filesize'] / 1048576),
1112 '^X' => $this->phpThumbObject->getimagesizeinfo[0],
1113 '^Y' => $this->phpThumbObject->getimagesizeinfo[1],
1114 '^x' => ImageSX($gdimg),
1115 '^y' => ImageSY($gdimg),
1116 '^^' => '^',
1117 );
1118 $text = strtr($text, $metaTextArray);
1119
1120 $text = str_replace("\r\n", "\n", $text);
1121 $text = str_replace("\r", "\n", $text);
1122 $textlines = explode("\n", $text);
1123 $this->DebugMessage('Processing '.count($textlines).' lines of text', __FILE__, __LINE__);
1124
1125 if (@is_readable($ttffont) && is_file($ttffont)) {
1126
1127 $opacity = 100 - intval(max(min($opacity, 100), 0));
1128 $letter_color_text = phpthumb_functions::ImageHexColorAllocate($gdimg, $hex_color, false, $opacity * 1.27);
1129
1130 $this->DebugMessage('Using TTF font "'.$ttffont.'"', __FILE__, __LINE__);
1131
1132 $TTFbox = ImageTTFbBox($size, $angle, $ttffont, $text);
1133
1134 $min_x = min($TTFbox[0], $TTFbox[2], $TTFbox[4], $TTFbox[6]);
1135 $max_x = max($TTFbox[0], $TTFbox[2], $TTFbox[4], $TTFbox[6]);
1136 //$text_width = round($max_x - $min_x + ($size * 0.5));
1137 $text_width = round($max_x - $min_x);
1138
1139 $min_y = min($TTFbox[1], $TTFbox[3], $TTFbox[5], $TTFbox[7]);
1140 $max_y = max($TTFbox[1], $TTFbox[3], $TTFbox[5], $TTFbox[7]);
1141 //$text_height = round($max_y - $min_y + ($size * 0.5));
1142 $text_height = round($max_y - $min_y);
1143
1144 $TTFboxChar = ImageTTFbBox($size, $angle, $ttffont, 'jH');
1145 $char_min_y = min($TTFboxChar[1], $TTFboxChar[3], $TTFboxChar[5], $TTFboxChar[7]);
1146 $char_max_y = max($TTFboxChar[1], $TTFboxChar[3], $TTFboxChar[5], $TTFboxChar[7]);
1147 $char_height = round($char_max_y - $char_min_y);
1148
1149 if ($alignment == '*') {
1150
1151 $text_origin_y = $char_height + $margin;
1152 while (($text_origin_y - $text_height) < ImageSY($gdimg)) {
1153 $text_origin_x = $margin;
1154 while ($text_origin_x < ImageSX($gdimg)) {
1155 ImageTTFtext($gdimg, $size, $angle, $text_origin_x, $text_origin_y, $letter_color_text, $ttffont, $text);
1156 $text_origin_x += ($text_width + $margin);
1157 }
1158 $text_origin_y += ($text_height + $margin);
1159 }
1160
1161 } else {
1162
1163 // this block for background color only
1164
1165 switch ($alignment) {
1166 case '*':
1167 // handled separately
1168 break;
1169
1170 case 'T':
1171 $text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width / 2) : round((ImageSX($gdimg) - $text_width) / 2));
1172 $text_origin_y = $char_height + $margin + $originOffsetY;
1173 break;
1174
1175 case 'B':
1176 $text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width / 2) : round((ImageSX($gdimg) - $text_width) / 2));
1177 $text_origin_y = ImageSY($gdimg) + $TTFbox[1] - $margin + $originOffsetY;
1178 break;
1179
1180 case 'L':
1181 $text_origin_x = $margin + $originOffsetX;
1182 $text_origin_y = ($originOffsetY ? $originOffsetY : round((ImageSY($gdimg) - $text_height) / 2) + $char_height);
1183 break;
1184
1185 case 'R':
1186 $text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : ImageSX($gdimg) - $text_width + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1187 $text_origin_y = ($originOffsetY ? $originOffsetY : round((ImageSY($gdimg) - $text_height) / 2) + $char_height);
1188 break;
1189
1190 case 'C':
1191 $text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width / 2) : round((ImageSX($gdimg) - $text_width) / 2));
1192 $text_origin_y = ($originOffsetY ? $originOffsetY : round((ImageSY($gdimg) - $text_height) / 2) + $char_height);
1193 break;
1194
1195 case 'TL':
1196 $text_origin_x = $margin + $originOffsetX;
1197 $text_origin_y = $char_height + $margin + $originOffsetY;
1198 break;
1199
1200 case 'TR':
1201 $text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : ImageSX($gdimg) - $text_width + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1202 $text_origin_y = $char_height + $margin + $originOffsetY;
1203 break;
1204
1205 case 'BL':
1206 $text_origin_x = $margin + $originOffsetX;
1207 $text_origin_y = ImageSY($gdimg) + $TTFbox[1] - $margin + $originOffsetY;
1208 break;
1209
1210 case 'BR':
1211 default:
1212 $text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : ImageSX($gdimg) - $text_width + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1213 $text_origin_y = ImageSY($gdimg) + $TTFbox[1] - $margin + $originOffsetY;
1214 break;
1215 }
1216
1217 //ImageRectangle($gdimg, $text_origin_x + $min_x, $text_origin_y + $TTFbox[1], $text_origin_x + $min_x + $text_width, $text_origin_y + $TTFbox[1] - $text_height, $letter_color_text);
1218 if (phpthumb_functions::IsHexColor($bg_color)) {
1219 $text_background_alpha = round(127 * ((100 - min(max(0, $bg_opacity), 100)) / 100));
1220 $text_color_background = phpthumb_functions::ImageHexColorAllocate($gdimg, $bg_color, false, $text_background_alpha);
1221 } else {
1222 $text_color_background = phpthumb_functions::ImageHexColorAllocate($gdimg, 'FFFFFF', false, 127);
1223 }
1224 $x1 = $text_origin_x + $min_x;
1225 $y1 = $text_origin_y + $TTFbox[1];
1226 $x2 = $text_origin_x + $min_x + $text_width;
1227 $y2 = $text_origin_y + $TTFbox[1] - $text_height;
1228 $x_TL = eregi('x', $fillextend) ? 0 : min($x1, $x2);
1229 $y_TL = eregi('y', $fillextend) ? 0 : min($y1, $y2);
1230 $x_BR = eregi('x', $fillextend) ? ImageSX($gdimg) : max($x1, $x2);
1231 $y_BR = eregi('y', $fillextend) ? ImageSY($gdimg) : max($y1, $y2);
1232 //while ($y_BR > ImageSY($gdimg)) {
1233 // $y_TL--;
1234 // $y_BR--;
1235 // $text_origin_y--;
1236 //}
1237 $this->DebugMessage('WatermarkText() calling ImageFilledRectangle($gdimg, '.$x_TL.', '.$y_TL.', '.$x_BR.', '.$y_BR.', $text_color_background)', __FILE__, __LINE__);
1238 ImageFilledRectangle($gdimg, $x_TL, $y_TL, $x_BR, $y_BR, $text_color_background);
1239
1240 // end block for background color only
1241
1242
1243 $y_offset = 0;
1244 foreach ($textlines as $dummy => $line) {
1245
1246 $TTFboxLine = ImageTTFbBox($size, $angle, $ttffont, $line);
1247 $min_x_line = min($TTFboxLine[0], $TTFboxLine[2], $TTFboxLine[4], $TTFboxLine[6]);
1248 $max_x_line = max($TTFboxLine[0], $TTFboxLine[2], $TTFboxLine[4], $TTFboxLine[6]);
1249 //$text_width = round($max_x - $min_x + ($size * 0.5));
1250 $text_width_line = round($max_x_line - $min_x_line);
1251
1252 $min_y_line = min($TTFboxLine[1], $TTFboxLine[3], $TTFboxLine[5], $TTFboxLine[7]);
1253 $max_y_line = max($TTFboxLine[1], $TTFboxLine[3], $TTFboxLine[5], $TTFboxLine[7]);
1254 //$text_height = round($max_y - $min_y + ($size * 0.5));
1255 $text_height_line = round($max_y_line - $min_y_line);
1256
1257 switch ($alignment) {
1258 // $text_origin_y set above, just re-set $text_origin_x here as needed
1259
1260 case 'L':
1261 case 'TL':
1262 case 'BL':
1263 // no change neccesary
1264 break;
1265
1266 case 'C':
1267 case 'T':
1268 case 'B':
1269 $text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width_line / 2) : round((ImageSX($gdimg) - $text_width_line) / 2));
1270 break;
1271
1272 case 'R':
1273 case 'TR':
1274 case 'BR':
1275 $text_origin_x = ($originOffsetX ? $originOffsetX - $text_width_line : ImageSX($gdimg) - $text_width_line + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1276 break;
1277 }
1278
1279 //ImageTTFtext($gdimg, $size, $angle, $text_origin_x, $text_origin_y, $letter_color_text, $ttffont, $text);
1280 $this->DebugMessage('WatermarkText() calling ImageTTFtext($gdimg, '.$size.', '.$angle.', '.$text_origin_x.', '.($text_origin_y + $y_offset).', $letter_color_text, '.$ttffont.', '.$line.')', __FILE__, __LINE__);
1281 ImageTTFtext($gdimg, $size, $angle, $text_origin_x, $text_origin_y + $y_offset, $letter_color_text, $ttffont, $line);
1282
1283 $y_offset += $char_height;
1284 }
1285
1286 }
1287 return true;
1288
1289 } else {
1290
1291 $size = min(5, max(1, $size));
1292 $this->DebugMessage('Using built-in font (size='.$size.') for text watermark'.($ttffont ? ' because $ttffont !is_readable('.$ttffont.')' : ''), __FILE__, __LINE__);
1293
1294 $text_width = 0;
1295 $text_height = 0;
1296 foreach ($textlines as $dummy => $line) {
1297 $text_width = max($text_width, ImageFontWidth($size) * strlen($line));
1298 $text_height += ImageFontHeight($size);
1299 }
1300 if ($img_watermark = phpthumb_functions::ImageCreateFunction($text_width, $text_height)) {
1301 ImageAlphaBlending($img_watermark, false);
1302 if (phpthumb_functions::IsHexColor($bg_color)) {
1303 $text_background_alpha = round(127 * ((100 - min(max(0, $bg_opacity), 100)) / 100));
1304 $text_color_background = phpthumb_functions::ImageHexColorAllocate($img_watermark, $bg_color, false, $text_background_alpha);
1305 } else {
1306 $text_color_background = phpthumb_functions::ImageHexColorAllocate($img_watermark, 'FFFFFF', false, 127);
1307 }
1308 $this->DebugMessage('WatermarkText() calling ImageFilledRectangle($img_watermark, 0, 0, '.ImageSX($img_watermark).', '.ImageSY($img_watermark).', $text_color_background)', __FILE__, __LINE__);
1309 ImageFilledRectangle($img_watermark, 0, 0, ImageSX($img_watermark), ImageSY($img_watermark), $text_color_background);
1310
1311 if ($angle && function_exists('ImageRotate')) {
1312 // using $img_watermark_mask is pointless if ImageRotate function isn't available
1313 if ($img_watermark_mask = phpthumb_functions::ImageCreateFunction($text_width, $text_height)) {
1314 $mask_color_background = ImageColorAllocate($img_watermark_mask, 0, 0, 0);
1315 ImageAlphaBlending($img_watermark_mask, false);
1316 ImageFilledRectangle($img_watermark_mask, 0, 0, ImageSX($img_watermark_mask), ImageSY($img_watermark_mask), $mask_color_background);
1317 $mask_color_watermark = ImageColorAllocate($img_watermark_mask, 255, 255, 255);
1318 }
1319 }
1320
1321 $text_color_watermark = phpthumb_functions::ImageHexColorAllocate($img_watermark, $hex_color);
1322 foreach ($textlines as $key => $line) {
1323 switch ($alignment) {
1324 case 'C':
1325 $x_offset = round(($text_width - (ImageFontWidth($size) * strlen($line))) / 2);
1326 $originOffsetX = (ImageSX($gdimg) - ImageSX($img_watermark)) / 2;
1327 $originOffsetY = (ImageSY($gdimg) - ImageSY($img_watermark)) / 2;
1328 break;
1329
1330 case 'T':
1331 $x_offset = round(($text_width - (ImageFontWidth($size) * strlen($line))) / 2);
1332 $originOffsetX = (ImageSX($gdimg) - ImageSX($img_watermark)) / 2;
1333 $originOffsetY = $margin;
1334 break;
1335
1336 case 'B':
1337 $x_offset = round(($text_width - (ImageFontWidth($size) * strlen($line))) / 2);
1338 $originOffsetX = (ImageSX($gdimg) - ImageSX($img_watermark)) / 2;
1339 $originOffsetY = ImageSY($gdimg) - ImageSY($img_watermark) - $margin;
1340 break;
1341
1342 case 'L':
1343 $x_offset = 0;
1344 $originOffsetX = $margin;
1345 $originOffsetY = (ImageSY($gdimg) - ImageSY($img_watermark)) / 2;
1346 break;
1347
1348 case 'TL':
1349 $x_offset = 0;
1350 $originOffsetX = $margin;
1351 $originOffsetY = $margin;
1352 break;
1353
1354 case 'BL':
1355 $x_offset = 0;
1356 $originOffsetX = $margin;
1357 $originOffsetY = ImageSY($gdimg) - ImageSY($img_watermark) - $margin;
1358 break;
1359
1360 case 'R':
1361 $x_offset = $text_width - (ImageFontWidth($size) * strlen($line));
1362 $originOffsetX = ImageSX($gdimg) - ImageSX($img_watermark) - $margin;
1363 $originOffsetY = (ImageSY($gdimg) - ImageSY($img_watermark)) / 2;
1364 break;
1365
1366 case 'TR':
1367 $x_offset = $text_width - (ImageFontWidth($size) * strlen($line));
1368 $originOffsetX = ImageSX($gdimg) - ImageSX($img_watermark) - $margin;
1369 $originOffsetY = $margin;
1370 break;
1371
1372 case 'BR':
1373 default:
1374 $x_offset = $text_width - (ImageFontWidth($size) * strlen($line));
1375 $originOffsetX = ImageSX($gdimg) - ImageSX($img_watermark) - $margin;
1376 $originOffsetY = ImageSY($gdimg) - ImageSY($img_watermark) - $margin;
1377 break;
1378 }
1379 $this->DebugMessage('WatermarkText() calling ImageString($img_watermark, '.$size.', '.$x_offset.', '.($key * ImageFontHeight($size)).', '.$line.', $text_color_watermark)', __FILE__, __LINE__);
1380 ImageString($img_watermark, $size, $x_offset, $key * ImageFontHeight($size), $line, $text_color_watermark);
1381 if ($angle && $img_watermark_mask) {
1382 $this->DebugMessage('WatermarkText() calling ImageString($img_watermark_mask, '.$size.', '.$x_offset.', '.($key * ImageFontHeight($size)).', '.$text.', $mask_color_watermark)', __FILE__, __LINE__);
1383 ImageString($img_watermark_mask, $size, $x_offset, $key * ImageFontHeight($size), $text, $mask_color_watermark);
1384 }
1385 }
1386 if ($angle && $img_watermark_mask) {
1387 $img_watermark = ImageRotate($img_watermark, $angle, $text_color_background);
1388 $img_watermark_mask = ImageRotate($img_watermark_mask, $angle, $mask_color_background);
1389 phpthumb_filters::ApplyMask($img_watermark_mask, $img_watermark);
1390 }
1391 //phpthumb_filters::WatermarkOverlay($gdimg, $img_watermark, $alignment, $opacity, $margin);
1392 $this->DebugMessage('WatermarkText() calling phpthumb_filters::WatermarkOverlay($gdimg, $img_watermark, '.($originOffsetX.'x'.$originOffsetY).', '.$opacity.', 0)', __FILE__, __LINE__);
1393 phpthumb_filters::WatermarkOverlay($gdimg, $img_watermark, $originOffsetX.'x'.$originOffsetY, $opacity, 0);
1394 ImageDestroy($img_watermark);
1395 return true;
1396 }
1397
1398 }
1399 return false;
1400 }
1401
1402
1403 function WatermarkOverlay(&$gdimg_dest, &$img_watermark, $alignment='*', $opacity=50, $margin_x=5, $margin_y=null) {
1404
1405 if (is_resource($gdimg_dest) && is_resource($img_watermark)) {
1406 $watermark_source_x = 0;
1407 $watermark_source_y = 0;
1408 $img_source_width = ImageSX($gdimg_dest);
1409 $img_source_height = ImageSY($gdimg_dest);
1410 $watermark_source_width = ImageSX($img_watermark);
1411 $watermark_source_height = ImageSY($img_watermark);
1412 $watermark_opacity_percent = max(0, min(100, $opacity));
1413 $margin_y = (is_null($margin_y) ? $margin_x : $margin_y);
1414 $watermark_margin_x = ((($margin_x > 0) && ($margin_x < 1)) ? round((1 - $margin_x) * $img_source_width) : $margin_x);
1415 $watermark_margin_y = ((($margin_y > 0) && ($margin_y < 1)) ? round((1 - $margin_y) * $img_source_height) : $margin_y);
1416 if (eregi('^([0-9\\.\\-]*)x([0-9\\.\\-]*)$', $alignment, $matches)) {
1417 $watermark_destination_x = intval($matches[1]);
1418 $watermark_destination_y = intval($matches[2]);
1419 } else {
1420 switch ($alignment) {
1421 case '*':
1422 if ($gdimg_tiledwatermark = phpthumb_functions::ImageCreateFunction($img_source_width, $img_source_height)) {
1423
1424 ImageAlphaBlending($gdimg_tiledwatermark, false);
1425 ImageSaveAlpha($gdimg_tiledwatermark, true);
1426 $text_color_transparent = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_tiledwatermark, 255, 0, 255, 127);
1427 ImageFill($gdimg_tiledwatermark, 0, 0, $text_color_transparent);
1428
1429 // set the tiled image transparent color to whatever the untiled image transparency index is
1430 // ImageColorTransparent($gdimg_tiledwatermark, ImageColorTransparent($img_watermark));
1431
1432 // a "cleaner" way of doing it, but can't handle the margin feature :(
1433 // ImageSetTile($gdimg_tiledwatermark, $img_watermark);
1434 // ImageFill($gdimg_tiledwatermark, 0, 0, IMG_COLOR_TILED);
1435 // break;
1436
1437 // ImageFill($gdimg_tiledwatermark, 0, 0, ImageColorTransparent($gdimg_tiledwatermark));
1438 // tile the image as many times as can fit
1439 for ($x = $watermark_margin_x; $x < ($img_source_width + $watermark_source_width); $x += ($watermark_source_width + $watermark_margin_x)) {
1440 for ($y = $watermark_margin_y; $y < ($img_source_height + $watermark_source_height); $y += ($watermark_source_height + $watermark_margin_y)) {
1441 ImageCopy(
1442 $gdimg_tiledwatermark,
1443 $img_watermark,
1444 $x,
1445 $y,
1446 0,
1447 0,
1448 min($watermark_source_width, $img_source_width - $x - $watermark_margin_x),
1449 min($watermark_source_height, $img_source_height - $y - $watermark_margin_y)
1450 );
1451 }
1452 }
1453
1454 $watermark_source_width = ImageSX($gdimg_tiledwatermark);
1455 $watermark_source_height = ImageSY($gdimg_tiledwatermark);
1456 $watermark_destination_x = 0;
1457 $watermark_destination_y = 0;
1458
1459 ImageDestroy($img_watermark);
1460 $img_watermark = $gdimg_tiledwatermark;
1461 }
1462 break;
1463
1464 case 'T':
1465 $watermark_destination_x = round((($img_source_width / 2) - ($watermark_source_width / 2)) + $watermark_margin_x);
1466 $watermark_destination_y = $watermark_margin_y;
1467 break;
1468
1469 case 'B':
1470 $watermark_destination_x = round((($img_source_width / 2) - ($watermark_source_width / 2)) + $watermark_margin_x);
1471 $watermark_destination_y = $img_source_height - $watermark_source_height - $watermark_margin_y;
1472 break;
1473
1474 case 'L':
1475 $watermark_destination_x = $watermark_margin_x;
1476 $watermark_destination_y = round((($img_source_height / 2) - ($watermark_source_height / 2)) + $watermark_margin_y);
1477 break;
1478
1479 case 'R':
1480 $watermark_destination_x = $img_source_width - $watermark_source_width - $watermark_margin_x;
1481 $watermark_destination_y = round((($img_source_height / 2) - ($watermark_source_height / 2)) + $watermark_margin_y);
1482 break;
1483
1484 case 'C':
1485 $watermark_destination_x = round(($img_source_width / 2) - ($watermark_source_width / 2));
1486 $watermark_destination_y = round(($img_source_height / 2) - ($watermark_source_height / 2));
1487 break;
1488
1489 case 'TL':
1490 $watermark_destination_x = $watermark_margin_x;
1491 $watermark_destination_y = $watermark_margin_y;
1492 break;
1493
1494 case 'TR':
1495 $watermark_destination_x = $img_source_width - $watermark_source_width - $watermark_margin_x;
1496 $watermark_destination_y = $watermark_margin_y;
1497 break;
1498
1499 case 'BL':
1500 //echo '<pre>';
1501 ////var_dump($watermark_destination_x);
1502 ////var_dump($watermark_destination_y);
1503 //var_dump($watermark_margin_x);
1504 //var_dump($img_source_height);
1505 //var_dump($watermark_source_height);
1506 //var_dump($watermark_margin_y);
1507 $watermark_destination_x = $watermark_margin_x;
1508 $watermark_destination_y = $img_source_height - $watermark_source_height - $watermark_margin_y;
1509 break;
1510
1511 case 'BR':
1512 default:
1513 $watermark_destination_x = $img_source_width - $watermark_source_width - $watermark_margin_x;
1514 $watermark_destination_y = $img_source_height - $watermark_source_height - $watermark_margin_y;
1515 break;
1516 }
1517 }
1518 ImageAlphaBlending($gdimg_dest, false);
1519 ImageSaveAlpha($gdimg_dest, true);
1520 ImageSaveAlpha($img_watermark, true);
1521 phpthumb_functions::ImageCopyRespectAlpha($gdimg_dest, $img_watermark, $watermark_destination_x, $watermark_destination_y, 0, 0, $watermark_source_width, $watermark_source_height, $watermark_opacity_percent);
1522
1523 return true;
1524 }
1525 return false;
1526 }
1527
1528
1529 function DebugMessage($message, $file='', $line='') {
1530 if (is_object($this->phpThumbObject)) {
1531 return $this->phpThumbObject->DebugMessage($message, $file, $line);
1532 }
1533 return false;
1534 }
1535}
1536
1537?>
Note: See TracBrowser for help on using the repository browser.