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