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: }
309:
310: $filename = $img;
311: $maxX = (int) $maxX;
312: $maxY = (int) $maxY;
313: $cacheTime = (int) $cacheTime;
314: $quality = (int) $quality;
315:
316: if ($quality <= 0 || $quality > 100) {
317: $quality = 75;
318: }
319:
320: $frontendURL = cRegistry::getFrontendUrl();
321: $filetype = substr($filename, strlen($filename) - 4, 4);
322: $md5 = cApiImgScaleGetMD5CacheFile($img, $maxX, $maxY, $crop, $expand);
323: $cfileName = cApiImageGetCacheFileName($md5, $filetype, $keepType);
324: $cacheFile = $cfgClient[$client]['cache']['path'] . $cfileName;
325: $webFile = $frontendURL . 'cache/' . $cfileName;
326:
327: if (cApiImageCheckCachedImageValidity($cacheFile, $cacheTime)) {
328: return $webFile;
329: }
330:
331: list($x, $y) = @getimagesize($filename);
332: if ($x == 0 || $y == 0) {
333: return false;
334: }
335:
336: list($targetX, $targetY) = cApiImageGetTargetDimensions($x, $y, $maxX, $maxY, $expand);
337:
338:
339: if ($filetype == '.gif') {
340: if (cApiImageIsAnimGif($filename)) {
341: $filename .= '[0]';
342: }
343: }
344:
345:
346: $output = array();
347: $retVal = 0;
348: $imPath = $cfg['images']['image_magick']['path'];
349: $program = escapeshellarg($imPath . 'convert');
350: $source = escapeshellarg($filename);
351: $destination = escapeshellarg($cacheFile);
352: if ($crop) {
353: $cmd = "{$program} -gravity center -quality {$quality} -crop {$maxX}x{$maxY}+1+1 {$source} {$destination}";
354: } else {
355: $cmd = "{$program} -quality {$quality} -geometry {$targetX}x{$targetY} {$source} {$destination}";
356: }
357:
358: exec($cmd, $output, $retVal);
359:
360: if (!cFileHandler::exists($cacheFile)) {
361: return false;
362: } else {
363: return $webFile;
364: }
365: }
366:
367: 368: 369: 370: 371: 372:
373: function cApiImageIsAnimGif($sFile) {
374: global $cfg;
375:
376: if ('im' != cApiImageCheckImageEditingPosibility()) {
377:
378: return false;
379: }
380:
381: $output = array();
382: $retval = 0;
383: $imPath = $cfg['images']['image_magick']['path'];
384: $program = escapeshellarg($imPath . 'identify');
385: $source = escapeshellarg($sFile);
386:
387: exec("{$program} {$source}", $output, $retval);
388:
389: if (count($output) == 1) {
390: return false;
391: }
392:
393: return true;
394: }
395:
396: 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: function cApiImgScale($img, $maxX, $maxY, $crop = false, $expand = false, $cacheTime = 10, $wantHQ = false, $quality = 75, $keepType = true) {
423: global $client, $cfgClient;
424:
425: $deleteAfter = false;
426:
427: $sRelativeImg = str_replace($cfgClient[$client]['upl']['path'], '', $img);
428: if (cApiDbfs::isDbfs($sRelativeImg)) {
429:
430: $dbfs = new cApiDbfsCollection();
431:
432: $file = basename($sRelativeImg);
433:
434: $dbfs->writeToFile($sRelativeImg, $cfgClient[$client]['cache']['path'] . $file);
435:
436: $img = $cfgClient[$client]['cache']['path'] . $file;
437: $deleteAfter = true;
438: } else if (!cFileHandler::exists($img)) {
439:
440: if (cFileHandler::exists($cfgClient[$client]['upl']['path'] . $img) && !is_dir($cfgClient[$client]['upl']['path'] . $img)) {
441: $img = $cfgClient[$client]['upl']['path'] . $img;
442: } else {
443:
444: return false;
445: }
446: }
447:
448: $filename = $img;
449: $filetype = substr($filename, strlen($filename) - 4, 4);
450:
451: $mxdAvImgEditingPosibility = cApiImageCheckImageEditingPosibility();
452: switch ($mxdAvImgEditingPosibility) {
453: case '1':
454: $method = 'gd1';
455: if (!function_exists('imagecreatefromgif') && $filetype == '.gif') {
456: $method = 'failure';
457: }
458: break;
459: case '2':
460: $method = 'gd2';
461: if (!function_exists('imagecreatefromgif') && $filetype == '.gif') {
462: $method = 'failure';
463: }
464: break;
465: case 'im':
466: $method = 'im';
467: break;
468: case '0':
469: $method = 'failure';
470: break;
471: default:
472: $method = 'failure';
473: break;
474: }
475:
476: switch ($method) {
477: case 'gd1':
478: $return = cApiImgScaleLQ($img, $maxX, $maxY, $crop, $expand, $cacheTime, $quality, $keepType);
479: break;
480: case 'gd2':
481: $return = cApiImgScaleHQ($img, $maxX, $maxY, $crop, $expand, $cacheTime, $quality, $keepType);
482: break;
483: case 'im':
484: $return = cApiImgScaleImageMagick($img, $maxX, $maxY, $crop, $expand, $cacheTime, $quality, $keepType);
485: break;
486: case 'failure':
487: $frontendURL = cRegistry::getFrontendUrl();
488: $return = str_replace(cRegistry::getFrontendPath(), $frontendURL, $img);
489: break;
490: }
491:
492: if ($deleteAfter == true) {
493: unlink($img);
494: }
495:
496: return $return;
497: }
498:
499: 500: 501: 502: 503: 504: 505: 506: 507: 508: 509:
510: function cApiImageCheckImageEditingPosibility() {
511: global $cfg;
512:
513: if (cApiIsImageMagickAvailable()) {
514: if ($cfg['images']['image_magick']['use']) {
515: return 'im';
516: }
517: }
518:
519: if (!extension_loaded('gd')) {
520: return '0';
521: }
522:
523: if (function_exists('gd_info')) {
524: $sGDVersion = '';
525: $aGDInformations = gd_info();
526: if (preg_match('#([0-9\.])+#', $aGDInformations['GD Version'], $sGDVersion)) {
527: if ($sGDVersion[0] >= '2') {
528: return '2';
529: }
530: return '1';
531: }
532: return '1';
533: }
534: return '1';
535: }
536:
537: 538: 539: 540: 541: 542: 543: 544: 545:
546: function cApiImageGetTargetDimensions($x, $y, $maxX, $maxY, $expand) {
547: if (($maxX / $x) < ($maxY / $y)) {
548: $targetY = $y * ($maxX / $x);
549: $targetX = round($maxX);
550:
551:
552: if ($targetY < $maxY) {
553: $targetY = ceil($targetY);
554: } else {
555: $targetY = floor($targetY);
556: }
557: } else {
558: $targetX = $x * ($maxY / $y);
559: $targetY = round($maxY);
560:
561:
562: if ($targetX < $maxX) {
563: $targetX = ceil($targetX);
564: } else {
565: $targetX = floor($targetX);
566: }
567: }
568:
569: if ($expand == false && (($targetX > $x) || ($targetY > $y))) {
570: $targetX = $x;
571: $targetY = $y;
572: }
573:
574: $targetX = ($targetX != 0) ? $targetX : 1;
575: $targetY = ($targetY != 0) ? $targetY : 1;
576:
577: return array($targetX, $targetY);
578: }
579:
580: 581: 582: 583: 584: 585: 586:
587: function cApiImageGetCacheFileName($md5, $filetype, $keepType) {
588:
589: if ($keepType) {
590:
591:
592: switch (strtolower($filetype)) {
593: case '.png':
594: $fileName = $md5 . '.png';
595: break;
596: case '.gif':
597: $fileName = $md5 . '.gif';
598: break;
599: default:
600: $fileName = $md5 . '.jpg';
601: }
602: } else {
603: $fileName = $md5 . '.jpg';
604: }
605: return $fileName;
606: }
607:
608: 609: 610: 611: 612: 613:
614: function cApiImageCheckCachedImageValidity($cacheFile, $cacheTime) {
615:
616: if (cFileHandler::exists($cacheFile)) {
617: if ($cacheTime == 0) {
618:
619: return true;
620: } else if (!function_exists('md5_file')) {
621:
622: if ((filemtime($cacheFile) + (60 * $cacheTime)) < time()) {
623:
624: unlink($cacheFile);
625: } else {
626:
627: return true;
628: }
629: } else {
630: return true;
631: }
632: }
633:
634: return false;
635: }
636:
637: 638: 639: 640: 641:
642: function cApiIsImageMagickAvailable() {
643: global $cfg;
644: static $imagemagickAvailable = null;
645:
646:
647: if (is_bool($imagemagickAvailable)) {
648: return $imagemagickAvailable;
649: }
650:
651:
652: $output = array();
653: $retval = 0;
654: $imPath = $cfg['images']['image_magick']['path'];
655: $program = '"' . escapeshellcmd($imPath . 'convert') . '" -version';
656:
657: @exec($program, $output, $retval);
658:
659: if (!is_array($output) || count($output) == 0) {
660:
661: $imagemagickAvailable = false;
662: } else {
663:
664:
665: if (strpos($output[0], 'ImageMagick') !== false) {
666: $imagemagickAvailable = true;
667: } else {
668: $imagemagickAvailable = false;
669: }
670: }
671:
672: return $imagemagickAvailable;
673: }
674:
675: ?>