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