1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
20:
21: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
22:
23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
33: function cApiImgScaleGetMD5CacheFile($sImg, $iMaxX, $iMaxY, $bCrop, $bExpand) {
34: if (!cFileHandler::exists($sImg)) {
35: return false;
36: }
37:
38: $iFilesize = filesize($sImg);
39:
40: if (function_exists('md5_file')) {
41: $sMD5 = md5(implode('', array(
42: $sImg, md5_file($sImg), $iFilesize, $iMaxX, $iMaxY, $bCrop, $bExpand
43: )));
44: } else {
45: $sMD5 = md5(implode('', array(
46: $sImg, $iFilesize, $iMaxX, $iMaxY, $bCrop, $bExpand
47: )));
48: }
49:
50: return $sMD5;
51: }
52:
53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74:
75: function cApiImgScaleLQ($img, $maxX, $maxY, $crop = false, $expand = false, $cacheTime = 10, $quality = 75, $keepType = false) {
76: global $cfgClient, $client;
77:
78: if (!cFileHandler::exists($img)) {
79: return false;
80: }
81:
82: $filename = $img;
83: $maxX = (int) $maxX;
84: $maxY = (int) $maxY;
85: $cacheTime = (int) $cacheTime;
86: $quality = (int) $quality;
87:
88: if ($quality <= 0 || $quality > 100) {
89: $quality = 75;
90: }
91:
92: $frontendURL = cRegistry::getFrontendUrl();
93: $filetype = substr($filename, strlen($filename) - 4, 4);
94: $md5 = cApiImgScaleGetMD5CacheFile($img, $maxX, $maxY, $crop, $expand);
95: $cfileName = cApiImageGetCacheFileName($md5, $filetype, $keepType);
96: $cacheFile = $cfgClient[$client]['cache']['path'] . $cfileName;
97: $webFile = $frontendURL . 'cache/' . $cfileName;
98:
99: if (cApiImageCheckCachedImageValidity($cacheFile, $cacheTime)) {
100: return $webFile;
101: }
102:
103:
104: switch (strtolower($filetype)) {
105: case '.gif': $function = 'imagecreatefromgif';
106: break;
107: case '.png': $function = 'imagecreatefrompng';
108: break;
109: case '.jpg': $function = 'imagecreatefromjpeg';
110: break;
111: case 'jpeg': $function = 'imagecreatefromjpeg';
112: break;
113: default: return false;
114: }
115:
116: if (function_exists($function)) {
117: $imageHandle = @$function($filename);
118: }
119:
120:
121: if (!$imageHandle) {
122: return false;
123: }
124:
125: $x = imagesx($imageHandle);
126: $y = imagesy($imageHandle);
127:
128: list($targetX, $targetY) = cApiImageGetTargetDimensions($x, $y, $maxX, $maxY, $expand);
129:
130:
131: if ($crop) {
132:
133: $targetImage = imagecreate($maxX, $maxY);
134: imagecopy($targetImage, $imageHandle, 0, 0, 0, 0, $maxX, $maxY);
135: } else {
136:
137: $targetImage = imagecreate($targetX, $targetY);
138: imagecopyresized($targetImage, $imageHandle, 0, 0, 0, 0, $targetX, $targetY, $x, $y);
139: }
140:
141:
142: if ($keepType) {
143: switch (strtolower($filetype)) {
144: case '.png':
145: imagepng($targetImage, $cacheFile);
146: break;
147: case '.gif':
148: imagegif($targetImage, $cacheFile);
149: break;
150: default:
151: imagejpeg($targetImage, $cacheFile, $quality);
152: }
153: } else {
154: imagejpeg($targetImage, $cacheFile, $quality);
155: }
156:
157: return ($webFile);
158: }
159:
160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184:
185: function cApiImgScaleHQ($img, $maxX, $maxY, $crop = false, $expand = false, $cacheTime = 10, $quality = 75, $keepType = true)
186: {
187: global $cfgClient, $client;
188:
189: if (!cFileHandler::exists($img)) {
190: return false;
191: }
192:
193: $filename = $img;
194: $maxX = (int) $maxX;
195: $maxY = (int) $maxY;
196: $cacheTime = (int) $cacheTime;
197: $quality = (int) $quality;
198:
199: if ($quality <= 0 || $quality > 100) {
200: $quality = 75;
201: }
202:
203: $frontendURL = cRegistry::getFrontendUrl();
204: $filetype = cFileHandler::getExtension($filename);
205: $md5 = cApiImgScaleGetMD5CacheFile($img, $maxX, $maxY, $crop, $expand);
206: $cfileName = cApiImageGetCacheFileName($md5, $filetype, $keepType);
207: $cacheFile = $cfgClient[$client]['cache']['path'] . $cfileName;
208: $webFile = $frontendURL . 'cache/' . $cfileName;
209:
210: if (cApiImageCheckCachedImageValidity($cacheFile, $cacheTime)) {
211: return $webFile;
212: }
213:
214:
215: switch (strtolower($filetype)) {
216: case 'gif': $function = 'imagecreatefromgif'; break;
217: case 'png': $function = 'imagecreatefrompng'; break;
218: case 'jpg': $function = 'imagecreatefromjpeg'; break;
219: case 'jpeg': $function = 'imagecreatefromjpeg'; break;
220: default: return false;
221: }
222:
223: if (function_exists($function)) {
224: $imageHandle = @$function($filename);
225: }
226:
227:
228: if (!$imageHandle) {
229: return false;
230: }
231:
232: $x = imagesx($imageHandle);
233: $y = imagesy($imageHandle);
234:
235: list($targetX, $targetY) = cApiImageGetTargetDimensions($x, $y, $maxX, $maxY, $expand);
236:
237:
238: if ($crop) {
239:
240: $targetImage = imagecreatetruecolor($maxX, $maxY);
241:
242: $srcX = ($x - $maxX) / 2;
243: $srcY = ($y - $maxY) /2;
244:
245: imagecopy($targetImage, $imageHandle, 0, 0, $srcX, $srcY, $maxX, $maxY);
246: } else {
247:
248: $targetImage = imagecreatetruecolor($targetX, $targetY);
249:
250:
251: if (strtolower($filetype) == '.gif' or strtolower($filetype) == '.png') {
252: imagecolortransparent($targetImage, imagecolorallocatealpha($targetImage, 0, 0, 0, 127));
253: imagealphablending($targetImage, false);
254: imagesavealpha($targetImage, true);
255: }
256:
257: imagecopyresampled($targetImage, $imageHandle, 0, 0, 0, 0, $targetX, $targetY, $x, $y);
258: }
259:
260:
261: if ($keepType) {
262: switch (strtolower($filetype)) {
263: case '.png':
264: imagepng($targetImage, $cacheFile);
265: break;
266: case '.gif':
267: imagegif($targetImage, $cacheFile);
268: break;
269: default:
270: imagejpeg($targetImage, $cacheFile, $quality);
271: }
272: } else {
273: imagejpeg($targetImage, $cacheFile, $quality);
274: }
275:
276: return $webFile;
277: }
278:
279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302:
303: function cApiImgScaleImageMagick($img, $maxX, $maxY, $crop = false, $expand = false, $cacheTime = 10, $quality = 75, $keepType = false) {
304: global $cfg, $cfgClient, $client;
305:
306: if (!cFileHandler::exists($img)) {
307: return false;
308: } elseif (isFunctionDisabled('escapeshellarg') || isFunctionDisabled('exec')) {
309: return false;
310: }
311:
312: $filename = $img;
313: $maxX = (int) $maxX;
314: $maxY = (int) $maxY;
315: $cacheTime = (int) $cacheTime;
316: $quality = (int) $quality;
317:
318: if ($quality <= 0 || $quality > 100) {
319: $quality = 75;
320: }
321:
322: $frontendURL = cRegistry::getFrontendUrl();
323: $filetype = substr($filename, strlen($filename) - 4, 4);
324: $md5 = cApiImgScaleGetMD5CacheFile($img, $maxX, $maxY, $crop, $expand);
325: $cfileName = cApiImageGetCacheFileName($md5, $filetype, $keepType);
326: $cacheFile = $cfgClient[$client]['cache']['path'] . $cfileName;
327: $webFile = $frontendURL . 'cache/' . $cfileName;
328:
329: if (cApiImageCheckCachedImageValidity($cacheFile, $cacheTime)) {
330: return $webFile;
331: }
332:
333: list($x, $y) = @getimagesize($filename);
334: if ($x == 0 || $y == 0) {
335: return false;
336: }
337:
338: list($targetX, $targetY) = cApiImageGetTargetDimensions($x, $y, $maxX, $maxY, $expand);
339:
340:
341: if ($filetype == '.gif') {
342: if (cApiImageIsAnimGif($filename)) {
343: $filename .= '[0]';
344: }
345: }
346:
347:
348: $output = array();
349: $retVal = 0;
350: $program = escapeshellarg($cfg['images']['image_magick']['path'] . 'convert');
351: $source = escapeshellarg($filename);
352: $destination = escapeshellarg($cacheFile);
353: if ($crop) {
354: $cmd = "'{$program}' -gravity center -quality {$quality} -crop {$maxX}x{$maxY}+1+1 '{$source}' '{$destination}'";
355: } else {
356: $cmd = "'{$program}' -quality {$quality} -geometry {$targetX}x{$targetY} '{$source}' '{$destination}'";
357: }
358:
359: exec($cmd, $output, $retVal);
360:
361: if (!cFileHandler::exists($cacheFile)) {
362: return false;
363: } else {
364: return $webFile;
365: }
366: }
367:
368: 369: 370: 371: 372: 373:
374: function cApiImageIsAnimGif($sFile) {
375: global $cfg;
376:
377: if (isFunctionDisabled('escapeshellarg') || isFunctionDisabled('exec')) {
378:
379: return false;
380: } elseif ('im' != cApiImageCheckImageEditingPosibility()) {
381:
382: return false;
383: }
384:
385: $output = array();
386: $retval = 0;
387: $program = escapeshellarg($cfg['images']['image_magick']['path'] . 'identify');
388: $source = escapeshellarg($sFile);
389:
390: exec("'{$program}' '{$source}'", $output, $retval);
391:
392: if (count($output) == 1) {
393: return false;
394: }
395:
396: return true;
397: }
398:
399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410: 411: 412: 413: 414: 415: 416: 417: 418: 419: 420: 421: 422: 423: 424:
425: function cApiImgScale($img, $maxX, $maxY, $crop = false, $expand = false, $cacheTime = 10, $wantHQ = false, $quality = 75, $keepType = true) {
426: global $client, $cfgClient;
427:
428: $deleteAfter = false;
429:
430: $sRelativeImg = str_replace($cfgClient[$client]['upl']['path'], '', $img);
431: if (cApiDbfs::isDbfs($sRelativeImg)) {
432:
433: $dbfs = new cApiDbfsCollection();
434:
435: $file = basename($sRelativeImg);
436:
437: $dbfs->writeToFile($sRelativeImg, $cfgClient[$client]['cache']['path'] . $file);
438:
439: $img = $cfgClient[$client]['cache']['path'] . $file;
440: $deleteAfter = true;
441: } else if (!cFileHandler::exists($img)) {
442:
443: if (cFileHandler::exists($cfgClient[$client]['upl']['path'] . $img) && !is_dir($cfgClient[$client]['upl']['path'] . $img)) {
444: $img = $cfgClient[$client]['upl']['path'] . $img;
445: } else {
446:
447: return false;
448: }
449: }
450:
451: $filename = $img;
452: $filetype = substr($filename, strlen($filename) - 4, 4);
453:
454: $mxdAvImgEditingPosibility = cApiImageCheckImageEditingPosibility();
455: switch ($mxdAvImgEditingPosibility) {
456: case '1':
457: $method = 'gd1';
458: if (!function_exists('imagecreatefromgif') && $filetype == '.gif') {
459: $method = 'failure';
460: }
461: break;
462: case '2':
463: $method = 'gd2';
464: if (!function_exists('imagecreatefromgif') && $filetype == '.gif') {
465: $method = 'failure';
466: }
467: break;
468: case 'im':
469: $method = 'im';
470: break;
471: case '0':
472: $method = 'failure';
473: break;
474: default:
475: $method = 'failure';
476: break;
477: }
478:
479: switch ($method) {
480: case 'gd1':
481: $return = cApiImgScaleLQ($img, $maxX, $maxY, $crop, $expand, $cacheTime, $quality, $keepType);
482: break;
483: case 'gd2':
484: $return = cApiImgScaleHQ($img, $maxX, $maxY, $crop, $expand, $cacheTime, $quality, $keepType);
485: break;
486: case 'im':
487: $return = cApiImgScaleImageMagick($img, $maxX, $maxY, $crop, $expand, $cacheTime, $quality, $keepType);
488: break;
489: case 'failure':
490: $frontendURL = cRegistry::getFrontendUrl();
491: $return = str_replace(cRegistry::getFrontendPath(), $frontendURL, $img);
492: break;
493: }
494:
495: if ($deleteAfter == true) {
496: unlink($img);
497: }
498:
499: return $return;
500: }
501:
502: 503: 504: 505: 506: 507: 508: 509: 510: 511: 512:
513: function cApiImageCheckImageEditingPosibility() {
514: global $cfg;
515:
516: if ($cfg['images']['image_magick']['use']) {
517: if (cApiIsImageMagickAvailable()) {
518: return 'im';
519: }
520: }
521:
522: if (!extension_loaded('gd')) {
523: return '0';
524: }
525:
526: if (function_exists('gd_info')) {
527: $sGDVersion = '';
528: $aGDInformations = gd_info();
529: if (preg_match('#([0-9\.])+#', $aGDInformations['GD Version'], $sGDVersion)) {
530: if ($sGDVersion[0] >= '2') {
531: return '2';
532: }
533: return '1';
534: }
535: return '1';
536: }
537: return '1';
538: }
539:
540: 541: 542: 543: 544: 545: 546: 547: 548:
549: function cApiImageGetTargetDimensions($x, $y, $maxX, $maxY, $expand) {
550: if (($maxX / $x) < ($maxY / $y)) {
551: $targetY = $y * ($maxX / $x);
552: $targetX = round($maxX);
553:
554:
555: if ($targetY < $maxY) {
556: $targetY = ceil($targetY);
557: } else {
558: $targetY = floor($targetY);
559: }
560: } else {
561: $targetX = $x * ($maxY / $y);
562: $targetY = round($maxY);
563:
564:
565: if ($targetX < $maxX) {
566: $targetX = ceil($targetX);
567: } else {
568: $targetX = floor($targetX);
569: }
570: }
571:
572: if ($expand == false && (($targetX > $x) || ($targetY > $y))) {
573: $targetX = $x;
574: $targetY = $y;
575: }
576:
577: $targetX = ($targetX != 0) ? $targetX : 1;
578: $targetY = ($targetY != 0) ? $targetY : 1;
579:
580: return array($targetX, $targetY);
581: }
582:
583: 584: 585: 586: 587: 588: 589:
590: function cApiImageGetCacheFileName($md5, $filetype, $keepType) {
591:
592: if ($keepType) {
593:
594:
595: switch (strtolower($filetype)) {
596: case '.png':
597: $fileName = $md5 . '.png';
598: break;
599: case '.gif':
600: $fileName = $md5 . '.gif';
601: break;
602: default:
603: $fileName = $md5 . '.jpg';
604: }
605: } else {
606: $fileName = $md5 . '.jpg';
607: }
608: return $fileName;
609: }
610:
611: 612: 613: 614: 615: 616:
617: function cApiImageCheckCachedImageValidity($cacheFile, $cacheTime) {
618:
619: if (cFileHandler::exists($cacheFile)) {
620: if ($cacheTime == 0) {
621:
622: return true;
623: } else if (!function_exists('md5_file')) {
624:
625: if ((filemtime($cacheFile) + (60 * $cacheTime)) < time()) {
626:
627: unlink($cacheFile);
628: } else {
629:
630: return true;
631: }
632: } else {
633: return true;
634: }
635: }
636:
637: return false;
638: }
639:
640: 641: 642: 643: 644:
645: function cApiIsImageMagickAvailable() {
646: global $cfg;
647: static $imagemagickAvailable = NULL;
648:
649:
650: if (is_bool($imagemagickAvailable)) {
651: return $imagemagickAvailable;
652: }
653:
654:
655: if (isFunctionDisabled('escapeshellarg') || isFunctionDisabled('exec')) {
656: $imagemagickAvailable = false;
657: return $imagemagickAvailable;
658: }
659:
660:
661: $output = array();
662: $retval = 0;
663: $imPath = $cfg['images']['image_magick']['path'];
664: $program = escapeshellarg($cfg['images']['image_magick']['path'] . 'convert');
665: @exec("'{$program}' -version", $output, $retval);
666:
667: if (!is_array($output) || count($output) == 0) {
668:
669: $imagemagickAvailable = false;
670: } else {
671:
672:
673: if (strpos($output[0], 'ImageMagick') !== false) {
674: $imagemagickAvailable = true;
675: } else {
676: $imagemagickAvailable = false;
677: }
678: }
679:
680: return $imagemagickAvailable;
681: }
682:
683: ?>