PageRenderTime 53ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/revslider/inc_php/image_view.class.php

https://bitbucket.org/metrobee/tr.deconord.eu
PHP | 610 lines | 450 code | 93 blank | 67 comment | 74 complexity | bac3b87356f20e8f4a8bd7c2b5fed63f MD5 | raw file
  1. <?php
  2. class UniteImageViewRev{
  3. private $pathCache;
  4. private $pathImages;
  5. private $urlImages;
  6. private $filename = null;
  7. private $maxWidth = null;
  8. private $maxHeight = null;
  9. private $type = null;
  10. private $effect = null;
  11. private $effect_arg1 = null;
  12. private $effect_arg2 = null;
  13. const EFFECT_BW = "bw";
  14. const EFFECT_BRIGHTNESS = "bright";
  15. const EFFECT_CONTRAST = "contrast";
  16. const EFFECT_EDGE = "edge";
  17. const EFFECT_EMBOSS = "emboss";
  18. const EFFECT_BLUR = "blur";
  19. const EFFECT_BLUR3 = "blur3";
  20. const EFFECT_MEAN = "mean";
  21. const EFFECT_SMOOTH = "smooth";
  22. const EFFECT_DARK = "dark";
  23. const TYPE_EXACT = "exact";
  24. const TYPE_EXACT_TOP = "exacttop";
  25. private $jpg_quality = 81;
  26. public function __construct($pathCache,$pathImages,$urlImages){
  27. $this->pathCache = $pathCache;
  28. $this->pathImages = $pathImages;
  29. $this->urlImages = $urlImages;
  30. }
  31. /**
  32. *
  33. * set jpg quality output
  34. */
  35. public function setJPGQuality($quality){
  36. $this->jpg_quality = $quality;
  37. }
  38. /**
  39. *
  40. * get thumb url
  41. */
  42. public static function getUrlThumb($urlBase, $filename,$width=null,$height=null,$exact=false,$effect=null,$effect_param=null){
  43. $filename = urlencode($filename);
  44. $url = $urlBase."&img=$filename";
  45. if(!empty($width))
  46. $url .= "&w=".$width;
  47. if(!empty($height))
  48. $url .= "&h=".$height;
  49. if($exact == true){
  50. $url .= "&t=".self::TYPE_EXACT;
  51. }
  52. if(!empty($effect)){
  53. $url .= "&e=".$effect;
  54. if(!empty($effect_param))
  55. $url .= "&ea1=".$effect_param;
  56. }
  57. return($url);
  58. }
  59. /**
  60. *
  61. * throw error
  62. */
  63. private function throwError($message,$code=null){
  64. UniteFunctionsRev::throwError($message,$code);
  65. }
  66. /**
  67. *
  68. * get filename for thumbnail save / retrieve
  69. * TODO: do input validations - security measures
  70. */
  71. private function getThumbFilename(){
  72. $info = pathInfo($this->filename);
  73. //add dirname as postfix (if exists)
  74. $postfix = "";
  75. $dirname = UniteFunctionsRev::getVal($info, "dirname");
  76. if(!empty($dirname)){
  77. $postfix = str_replace("/", "-", $dirname);
  78. }
  79. $ext = $info["extension"];
  80. $name = $info["filename"];
  81. $width = ceil($this->maxWidth);
  82. $height = ceil($this->maxHeight);
  83. $thumbFilename = $name."_".$width."x".$height;
  84. if(!empty($this->type))
  85. $thumbFilename .= "_" . $this->type;
  86. if(!empty($this->effect)){
  87. $thumbFilename .= "_e" . $this->effect;
  88. if(!empty($this->effect_arg1)){
  89. $thumbFilename .= "x" . $this->effect_arg1;
  90. }
  91. }
  92. //add postfix
  93. if(!empty($postfix))
  94. $thumbFilename .= "_".$postfix;
  95. $thumbFilename .= ".".$ext;
  96. return($thumbFilename);
  97. }
  98. //------------------------------------------------------------------------------------------
  99. // get thumbnail fielpath by parameters.
  100. private function getThumbFilepath(){
  101. $filename = $this->getThumbFilename();
  102. $filepath = $this->pathCache .$filename;
  103. return($filepath);
  104. }
  105. //------------------------------------------------------------------------------------------
  106. // ouptput emtpy image code.
  107. private function outputEmptyImageCode(){
  108. echo "empty image";
  109. exit();
  110. }
  111. //------------------------------------------------------------------------------------------
  112. // outputs image and exit.
  113. private function outputImage($filepath){
  114. $info = UniteFunctionsRev::getPathInfo($filepath);
  115. $ext = $info["extension"];
  116. $filetime = filemtime($filepath);
  117. $ext = strtolower($ext);
  118. if($ext == "jpg")
  119. $ext = "jpeg";
  120. $numExpires = 31536000; //one year
  121. $strExpires = @date('D, d M Y H:i:s',time()+$numExpires);
  122. $strModified = @date('D, d M Y H:i:s',$filetime);
  123. $contents = file_get_contents($filepath);
  124. $filesize = strlen($contents);
  125. header("Last-Modified: $strModified GMT");
  126. header("Expires: $strExpires GMT");
  127. header("Cache-Control: public");
  128. header("Content-Type: image/$ext");
  129. header("Content-Length: $filesize");
  130. echo $contents;
  131. exit();
  132. }
  133. //------------------------------------------------------------------------------------------
  134. // get src image from filepath according the image type
  135. private function getGdSrcImage($filepath,$type){
  136. // create the image
  137. $src_img = false;
  138. switch($type){
  139. case IMAGETYPE_JPEG:
  140. $src_img = @imagecreatefromjpeg($filepath);
  141. break;
  142. case IMAGETYPE_PNG:
  143. $src_img = @imagecreatefrompng($filepath);
  144. break;
  145. case IMAGETYPE_GIF:
  146. $src_img = @imagecreatefromgif($filepath);
  147. break;
  148. case IMAGETYPE_BMP:
  149. $src_img = @imagecreatefromwbmp($filepath);
  150. break;
  151. default:
  152. $this->throwError("wrong image format, can't resize");
  153. break;
  154. }
  155. if($src_img == false){
  156. $this->throwError("Can't resize image");
  157. }
  158. return($src_img);
  159. }
  160. //------------------------------------------------------------------------------------------
  161. // save gd image to some filepath. return if success or not
  162. private function saveGdImage($dst_img,$filepath,$type){
  163. $successSaving = false;
  164. switch($type){
  165. case IMAGETYPE_JPEG:
  166. $successSaving = imagejpeg($dst_img,$filepath,$this->jpg_quality);
  167. break;
  168. case IMAGETYPE_PNG:
  169. $successSaving = imagepng($dst_img,$filepath);
  170. break;
  171. case IMAGETYPE_GIF:
  172. $successSaving = imagegif($dst_img,$filepath);
  173. break;
  174. case IMAGETYPE_BMP:
  175. $successSaving = imagewbmp($dst_img,$filepath);
  176. break;
  177. }
  178. return($successSaving);
  179. }
  180. //------------------------------------------------------------------------------------------
  181. // crop image to specifix height and width , and save it to new path
  182. private function cropImageSaveNew($filepath,$filepathNew){
  183. $imgInfo = getimagesize($filepath);
  184. $imgType = $imgInfo[2];
  185. $src_img = $this->getGdSrcImage($filepath,$imgType);
  186. $width = imageSX($src_img);
  187. $height = imageSY($src_img);
  188. //crop the image from the top
  189. $startx = 0;
  190. $starty = 0;
  191. //find precrop width and height:
  192. $percent = $this->maxWidth / $width;
  193. $newWidth = $this->maxWidth;
  194. $newHeight = ceil($percent * $height);
  195. if($this->type == "exact"){ //crop the image from the middle
  196. $startx = 0;
  197. $starty = ($newHeight-$this->maxHeight)/2 / $percent;
  198. }
  199. if($newHeight < $this->maxHeight){ //by width
  200. $percent = $this->maxHeight / $height;
  201. $newHeight = $this->maxHeight;
  202. $newWidth = ceil($percent * $width);
  203. if($this->type == "exact"){ //crop the image from the middle
  204. $startx = ($newWidth - $this->maxWidth) /2 / $percent; //the startx is related to big image
  205. $starty = 0;
  206. }
  207. }
  208. //resize the picture:
  209. $tmp_img = ImageCreateTrueColor($newWidth,$newHeight);
  210. $this->handleTransparency($tmp_img,$imgType,$newWidth,$newHeight);
  211. imagecopyresampled($tmp_img,$src_img,0,0,$startx,$starty,$newWidth,$newHeight,$width,$height);
  212. $this->handleImageEffects($tmp_img);
  213. //crop the picture:
  214. $dst_img = ImageCreateTrueColor($this->maxWidth,$this->maxHeight);
  215. $this->handleTransparency($dst_img,$imgType,$this->maxWidth,$this->maxHeight);
  216. imagecopy($dst_img, $tmp_img, 0, 0, 0, 0, $newWidth, $newHeight);
  217. //save the picture
  218. $is_saved = $this->saveGdImage($dst_img,$filepathNew,$imgType);
  219. imagedestroy($dst_img);
  220. imagedestroy($src_img);
  221. imagedestroy($tmp_img);
  222. return($is_saved);
  223. }
  224. //------------------------------------------------------------------------------------------
  225. // if the images are png or gif - handle image transparency
  226. private function handleTransparency(&$dst_img,$imgType,$newWidth,$newHeight){
  227. //handle transparency:
  228. if($imgType == IMAGETYPE_PNG || $imgType == IMAGETYPE_GIF){
  229. imagealphablending($dst_img, false);
  230. imagesavealpha($dst_img,true);
  231. $transparent = imagecolorallocatealpha($dst_img, 255, 255, 255, 127);
  232. imagefilledrectangle($dst_img, 0, 0, $newWidth, $newHeight, $transparent);
  233. }
  234. }
  235. //------------------------------------------------------------------------------------------
  236. // handle image effects
  237. private function handleImageEffects(&$imgHandle){
  238. if(empty($this->effect))
  239. return(false);
  240. switch($this->effect){
  241. case self::EFFECT_BW:
  242. if(defined("IMG_FILTER_GRAYSCALE"))
  243. imagefilter($imgHandle,IMG_FILTER_GRAYSCALE);
  244. break;
  245. case self::EFFECT_BRIGHTNESS:
  246. if(defined("IMG_FILTER_BRIGHTNESS")){
  247. if(!is_numeric($this->effect_arg1))
  248. $this->effect_arg1 = 50; //set default value
  249. UniteFunctionsRev::validateNumeric($this->effect_arg1,"'ea1' argument");
  250. imagefilter($imgHandle,IMG_FILTER_BRIGHTNESS,$this->effect_arg1);
  251. }
  252. break;
  253. case self::EFFECT_DARK:
  254. if(defined("IMG_FILTER_BRIGHTNESS")){
  255. if(!is_numeric($this->effect_arg1))
  256. $this->effect_arg1 = -50; //set default value
  257. UniteFunctionsRev::validateNumeric($this->effect_arg1,"'ea1' argument");
  258. imagefilter($imgHandle,IMG_FILTER_BRIGHTNESS,$this->effect_arg1);
  259. }
  260. break;
  261. case self::EFFECT_CONTRAST:
  262. if(defined("IMG_FILTER_CONTRAST")){
  263. if(!is_numeric($this->effect_arg1))
  264. $this->effect_arg1 = -5; //set default value
  265. imagefilter($imgHandle,IMG_FILTER_CONTRAST,$this->effect_arg1);
  266. }
  267. break;
  268. case self::EFFECT_EDGE:
  269. if(defined("IMG_FILTER_EDGEDETECT"))
  270. imagefilter($imgHandle,IMG_FILTER_EDGEDETECT);
  271. break;
  272. case self::EFFECT_EMBOSS:
  273. if(defined("IMG_FILTER_EMBOSS"))
  274. imagefilter($imgHandle,IMG_FILTER_EMBOSS);
  275. break;
  276. case self::EFFECT_BLUR:
  277. $this->effect_Blur($imgHandle,5);
  278. /*
  279. if(defined("IMG_FILTER_GAUSSIAN_BLUR"))
  280. imagefilter($imgHandle,IMG_FILTER_GAUSSIAN_BLUR);
  281. */
  282. break;
  283. case self::EFFECT_MEAN:
  284. if(defined("IMG_FILTER_MEAN_REMOVAL"))
  285. imagefilter($imgHandle,IMG_FILTER_MEAN_REMOVAL);
  286. break;
  287. case self::EFFECT_SMOOTH:
  288. if(defined("IMG_FILTER_SMOOTH")){
  289. if(!is_numeric($this->effect_arg1))
  290. $this->effect_arg1 = 15; //set default value
  291. imagefilter($imgHandle,IMG_FILTER_SMOOTH,$this->effect_arg1);
  292. }
  293. break;
  294. case self::EFFECT_BLUR3:
  295. $this->effect_Blur($imgHandle,5);
  296. break;
  297. default:
  298. $this->throwError("Effect not supported: <b>{$this->effect}</b>");
  299. break;
  300. }
  301. }
  302. private function effect_Blur(&$gdimg, $radius=0.5) {
  303. // Taken from Torstein Hרnsi's phpUnsharpMask (see phpthumb.unsharp.php)
  304. $radius = round(max(0, min($radius, 50)) * 2);
  305. if (!$radius) {
  306. return false;
  307. }
  308. $w = ImageSX($gdimg);
  309. $h = ImageSY($gdimg);
  310. if ($imgBlur = ImageCreateTrueColor($w, $h)) {
  311. // Gaussian blur matrix:
  312. // 1 2 1
  313. // 2 4 2
  314. // 1 2 1
  315. // Move copies of the image around one pixel at the time and merge them with weight
  316. // according to the matrix. The same matrix is simply repeated for higher radii.
  317. for ($i = 0; $i < $radius; $i++) {
  318. ImageCopy ($imgBlur, $gdimg, 0, 0, 1, 1, $w - 1, $h - 1); // up left
  319. ImageCopyMerge($imgBlur, $gdimg, 1, 1, 0, 0, $w, $h, 50.00000); // down right
  320. ImageCopyMerge($imgBlur, $gdimg, 0, 1, 1, 0, $w - 1, $h, 33.33333); // down left
  321. ImageCopyMerge($imgBlur, $gdimg, 1, 0, 0, 1, $w, $h - 1, 25.00000); // up right
  322. ImageCopyMerge($imgBlur, $gdimg, 0, 0, 1, 0, $w - 1, $h, 33.33333); // left
  323. ImageCopyMerge($imgBlur, $gdimg, 1, 0, 0, 0, $w, $h, 25.00000); // right
  324. ImageCopyMerge($imgBlur, $gdimg, 0, 0, 0, 1, $w, $h - 1, 20.00000); // up
  325. ImageCopyMerge($imgBlur, $gdimg, 0, 1, 0, 0, $w, $h, 16.666667); // down
  326. ImageCopyMerge($imgBlur, $gdimg, 0, 0, 0, 0, $w, $h, 50.000000); // center
  327. ImageCopy ($gdimg, $imgBlur, 0, 0, 0, 0, $w, $h);
  328. }
  329. return true;
  330. }
  331. return false;
  332. }
  333. //------------------------------------------------------------------------------------------
  334. // resize image and save it to new path
  335. private function resizeImageSaveNew($filepath,$filepathNew){
  336. $imgInfo = getimagesize($filepath);
  337. $imgType = $imgInfo[2];
  338. $src_img = $this->getGdSrcImage($filepath,$imgType);
  339. $width = imageSX($src_img);
  340. $height = imageSY($src_img);
  341. $newWidth = $width;
  342. $newHeight = $height;
  343. //find new width
  344. if($height > $this->maxHeight){
  345. $procent = $this->maxHeight / $height;
  346. $newWidth = ceil($width * $procent);
  347. $newHeight = $this->maxHeight;
  348. }
  349. //if the new width is grater than max width, find new height, and remain the width.
  350. if($newWidth > $this->maxWidth){
  351. $procent = $this->maxWidth / $newWidth;
  352. $newHeight = ceil($newHeight * $procent);
  353. $newWidth = $this->maxWidth;
  354. }
  355. //if the image don't need to be resized, just copy it from source to destanation.
  356. if($newWidth == $width && $newHeight == $height && empty($this->effect)){
  357. $success = copy($filepath,$filepathNew);
  358. if($success == false)
  359. $this->throwError("can't copy the image from one path to another");
  360. }
  361. else{ //else create the resized image, and save it to new path:
  362. $dst_img = ImageCreateTrueColor($newWidth,$newHeight);
  363. $this->handleTransparency($dst_img,$imgType,$newWidth,$newHeight);
  364. //copy the new resampled image:
  365. imagecopyresampled($dst_img,$src_img,0,0,0,0,$newWidth,$newHeight,$width,$height);
  366. $this->handleImageEffects($dst_img);
  367. $is_saved = $this->saveGdImage($dst_img,$filepathNew,$imgType);
  368. imagedestroy($dst_img);
  369. }
  370. imagedestroy($src_img);
  371. return(true);
  372. }
  373. /**
  374. *
  375. * set image effect
  376. */
  377. public function setEffect($effect,$arg1 = ""){
  378. $this->effect = $effect;
  379. $this->effect_arg1 = $arg1;
  380. }
  381. //------------------------------------------------------------------------------------------
  382. //return image
  383. private function showImage($filename,$maxWidth=-1,$maxHeight=-1,$type=""){
  384. if(empty($filename))
  385. $this->throwError("image filename not found");
  386. //validate input
  387. if($type == self::TYPE_EXACT || $type == self::TYPE_EXACT_TOP){
  388. if($maxHeight == -1)
  389. $this->throwError("image with exact type must have height!");
  390. if($maxWidth == -1)
  391. $this->throwError("image with exact type must have width!");
  392. }
  393. $filepath = $this->pathImages.$filename;
  394. if(!is_file($filepath)) $this->outputEmptyImageCode();
  395. //if gd library doesn't exists - output normal image without resizing.
  396. if(function_exists("gd_info") == false)
  397. $this->throwError("php must support GD Library");
  398. //check conditions for output original image
  399. if(empty($this->effect)){
  400. if((is_numeric($maxWidth) == false || is_numeric($maxHeight) == false)) outputImage($filepath);
  401. if($maxWidth == -1 && $maxHeight == -1)
  402. $this->outputImage($filepath);
  403. }
  404. if($maxWidth == -1) $maxWidth = 1000000;
  405. if($maxHeight == -1) $maxHeight = 100000;
  406. //init variables
  407. $this->filename = $filename;
  408. $this->maxWidth = $maxWidth;
  409. $this->maxHeight = $maxHeight;
  410. $this->type = $type;
  411. $filepathNew = $this->getThumbFilepath();
  412. if(is_file($filepathNew)){
  413. $this->outputImage($filepathNew);
  414. exit();
  415. }
  416. try{
  417. if($type == self::TYPE_EXACT || $type == self::TYPE_EXACT_TOP){
  418. $isSaved = $this->cropImageSaveNew($filepath,$filepathNew);
  419. }
  420. else
  421. $isSaved = $this->resizeImageSaveNew($filepath,$filepathNew);
  422. if($isSaved == false){
  423. $this->outputImage($filepath);
  424. exit();
  425. }
  426. }catch(Exception $e){
  427. $this->outputImage($filepath);
  428. }
  429. if(is_file($filepathNew))
  430. $this->outputImage($filepathNew);
  431. else
  432. $this->outputImage($filepath);
  433. exit();
  434. }
  435. /**
  436. *
  437. * show image from get params
  438. */
  439. public function showImageFromGet(){
  440. $imageFilename = UniteFunctionsRev::getGetVar("img");
  441. $maxWidth = UniteFunctionsRev::getGetVar("w",-1);
  442. $maxHeight = UniteFunctionsRev::getGetVar("h",-1);
  443. $type = UniteFunctionsRev::getGetVar("t","");
  444. //set effect
  445. $effect = UniteFunctionsRev::getGetVar("e");
  446. $effectArgument1 = UniteFunctionsRev::getGetVar("ea1");
  447. if(!empty($effect))
  448. $this->setEffect($effect,$effectArgument1);
  449. $this->showImage($imageFilename,$maxWidth,$maxHeight,$type);
  450. }
  451. //------------------------------------------------------------------------------------------
  452. // download image, change size and name if needed.
  453. public function downloadImage($filename){
  454. $filepath = $this->urlImages."/".$filename;
  455. if(!is_file($filepath)) {
  456. echo "file doesn't exists";
  457. exit();
  458. }
  459. $this->outputImageForDownload($filepath,$filename);
  460. }
  461. //------------------------------------------------------------------------------------------
  462. // output image for downloading
  463. private function outputImageForDownload($filepath,$filename,$mimeType=""){
  464. $contents = file_get_contents($filepath);
  465. $filesize = strlen($contents);
  466. if($mimeType == ""){
  467. $info = UniteFunctionsRev::getPathInfo($filepath);
  468. $ext = $info["extension"];
  469. $mimeType = "image/$ext";
  470. }
  471. header("Content-Type: $mimeType");
  472. header("Content-Disposition: attachment; filename=\"$filename\"");
  473. header("Content-Length: $filesize");
  474. echo $contents;
  475. exit();
  476. }
  477. /**
  478. *
  479. * validate type
  480. * @param unknown_type $type
  481. */
  482. public function validateType($type){
  483. switch($type){
  484. case self::TYPE_EXACT:
  485. case self::TYPE_EXACT_TOP:
  486. break;
  487. default:
  488. $this->throwError("Wrong image type: ".$type);
  489. break;
  490. }
  491. }
  492. }
  493. ?>