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