es_imagecls.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. <?php
  2. /**
  3. 图片处理类
  4. */
  5. class es_imagecls
  6. {
  7. /**
  8. * 文件信息
  9. */
  10. var $file = array();
  11. /**
  12. * 保存目录
  13. */
  14. var $dir = '';
  15. /**
  16. * 错误代码
  17. */
  18. var $error_code = 0;
  19. /**
  20. * 文件上传最大KB
  21. */
  22. var $max_size = -1;
  23. function es_imagecls()
  24. {
  25. }
  26. private function checkSize($size)
  27. {
  28. return !($size > $this->max_size) || (-1 == $this->max_size);
  29. }
  30. /**
  31. * 处理上传文件
  32. * @param array $file 上传的文件
  33. * @param string $dir 保存的目录
  34. * @return bool
  35. */
  36. function init($file, $dir = 'temp')
  37. {
  38. if(!is_array($file) || empty($file) || !$this->isUploadFile($file['tmp_name']) || trim($file['name']) == '' || $file['size'] == 0)
  39. {
  40. $this->file = array();
  41. $this->error_code = -1;
  42. return false;
  43. }
  44. else
  45. {
  46. $file['size'] = intval($file['size']);
  47. $file['name'] = trim($file['name']);
  48. $file['thumb'] = '';
  49. $file['ext'] = $this->fileExt($file['name']);
  50. $file['name'] = htmlspecialchars($file['name'], ENT_QUOTES);
  51. $file['is_image'] = $this->isImageExt($file['ext']);
  52. $file['file_dir'] = $this->getTargetDir($dir);
  53. $file['prefix'] = md5(microtime(true)).rand(10,99);
  54. $file['target'] = "./public/".$file['file_dir'].'/'.$file['prefix'].'.jpg'; //相对
  55. $file['local_target'] = APP_ROOT_PATH."public/".$file['file_dir'].'/'.$file['prefix'].'.jpg'; //物理
  56. $this->file = &$file;
  57. $this->error_code = 0;
  58. return true;
  59. }
  60. }
  61. /**
  62. * 保存文件
  63. * @return bool
  64. */
  65. function save()
  66. {
  67. if(empty($this->file) || empty($this->file['tmp_name']))
  68. $this->error_code = -101;
  69. elseif(!$this->checkSize($this->file['size']))
  70. $this->error_code = -105;
  71. elseif(!$this->file['is_image'])
  72. $this->error_code = -102;
  73. elseif(!$this->saveFile($this->file['tmp_name'], $this->file['local_target']))
  74. $this->error_code = -103;
  75. elseif($this->file['is_image'] && (!$this->file['image_info'] = $this->getImageInfo($this->file['local_target'], true)))
  76. {
  77. $this->error_code = -104;
  78. @unlink($this->file['local_target']);
  79. }
  80. else
  81. {
  82. $this->error_code = 0;
  83. return true;
  84. }
  85. return false;
  86. }
  87. /**
  88. * 获取错误代码
  89. * @return number
  90. */
  91. function error()
  92. {
  93. return $this->error_code;
  94. }
  95. /**
  96. * 获取文件扩展名
  97. * @return string
  98. */
  99. function fileExt($file_name)
  100. {
  101. return addslashes(strtolower(substr(strrchr($file_name, '.'), 1, 10)));
  102. }
  103. /**
  104. * 根据扩展名判断文件是否为图像
  105. * @param string $ext 扩展名
  106. * @return bool
  107. */
  108. function isImageExt($ext)
  109. {
  110. static $img_ext = array('jpg', 'jpeg', 'png', 'bmp','gif','giff');
  111. return in_array($ext, $img_ext) ? 1 : 0;
  112. }
  113. /**
  114. * 获取图像信息
  115. * @param string $target 文件路径
  116. * @return mixed
  117. */
  118. function getImageInfo($target)
  119. {
  120. $ext = es_imagecls::fileExt($target);
  121. $is_image = es_imagecls::isImageExt($ext);
  122. if(!$is_image)
  123. return false;
  124. elseif(!is_readable($target))
  125. return false;
  126. elseif($image_info = @getimagesize($target))
  127. {
  128. list($width, $height, $type) = !empty($image_info) ? $image_info : array('', '', '');
  129. $size = $width * $height;
  130. if($is_image && !in_array($type, array(1,2,3,6,13)))
  131. return false;
  132. $image_info['type'] = strtolower(substr(image_type_to_extension($image_info[2]),1));
  133. return $image_info;
  134. }
  135. else
  136. return false;
  137. }
  138. /**
  139. * 获取是否充许上传文件
  140. * @param string $source 文件路径
  141. * @return bool
  142. */
  143. function isUploadFile($source)
  144. {
  145. return $source && ($source != 'none') && (is_uploaded_file($source) || is_uploaded_file(str_replace('\\\\', '\\', $source)));
  146. }
  147. /**
  148. * 获取保存的路径
  149. * @param string $dir 指定的保存目录
  150. * @return string
  151. */
  152. function getTargetDir($dir)
  153. {
  154. if (!is_dir(APP_ROOT_PATH."public/".$dir)) {
  155. @mkdir(APP_ROOT_PATH."public/".$dir);
  156. @chmod(APP_ROOT_PATH."public/".$dir, 0777);
  157. }
  158. return $dir;
  159. }
  160. /**
  161. * 保存文件
  162. * @param string $source 源文件路径
  163. * @param string $target 目录文件路径
  164. * @return bool
  165. */
  166. private function saveFile($source, $target)
  167. {
  168. if(!es_imagecls::isUploadFile($source))
  169. $succeed = false;
  170. elseif(@copy($source, $target))
  171. $succeed = true;
  172. elseif(function_exists('move_uploaded_file') && @move_uploaded_file($source, $target))
  173. $succeed = true;
  174. elseif (@is_readable($source) && (@$fp_s = fopen($source, 'rb')) && (@$fp_t = fopen($target, 'wb')))
  175. {
  176. while (!feof($fp_s))
  177. {
  178. $s = @fread($fp_s, 1024 * 512);
  179. @fwrite($fp_t, $s);
  180. }
  181. fclose($fp_s);
  182. fclose($fp_t);
  183. $succeed = true;
  184. }
  185. if($succeed)
  186. {
  187. $this->error_code = 0;
  188. @chmod($target, 0644);
  189. @unlink($source);
  190. }
  191. else
  192. {
  193. $this->error_code = 0;
  194. }
  195. return $succeed;
  196. }
  197. /**
  198. * $gen 0 等比缩放 1等比缩放 白色填充 2 裁剪 已最小为基准
  199. */
  200. public function thumb($image,$maxWidth=200,$maxHeight=50,$gen = 0,$interlace=true,$filepath = '',$is_preview = true)
  201. {
  202. $info = es_imagecls::getImageInfo($image);
  203. if($info !== false)
  204. {
  205. $srcWidth = $info[0];
  206. $srcHeight = $info[1];
  207. $type = $info['type'];
  208. $interlace = $interlace? 1:0;
  209. unset($info);
  210. if($maxWidth > 0 && $maxHeight > 0)
  211. $scale = min($maxWidth/$srcWidth, $maxHeight/$srcHeight); // 计算缩放比例
  212. elseif($maxWidth == 0)
  213. $scale = $maxHeight/$srcHeight;
  214. elseif($maxHeight == 0)
  215. $scale = $maxWidth/$srcWidth;
  216. $paths = pathinfo($image);
  217. $paths['filename'] = trim(strtolower($paths['basename']),".".strtolower($paths['extension']));
  218. $basefilename = explode("_",$paths['filename']);
  219. $basefilename = $basefilename[0];
  220. if(empty($filepath))
  221. {
  222. if($is_preview)
  223. $thumbname = $paths['dirname'].'/'.$basefilename.'_'.$maxWidth.'x'.$maxHeight.'.jpg';
  224. else
  225. $thumbname = $paths['dirname'].'/'.$basefilename.'o_'.$maxWidth.'x'.$maxHeight.'.jpg';
  226. }
  227. else
  228. $thumbname = $filepath;
  229. $thumburl = str_replace(APP_ROOT_PATH,'./',$thumbname);
  230. if($scale >= 1)
  231. {
  232. // 超过原图大小不再缩略
  233. $width = $srcWidth;
  234. $height = $srcHeight;
  235. if(!$is_preview)
  236. {
  237. //非预览模式写入原图
  238. file_put_contents($thumbname,file_get_contents($image)); //用原图写入
  239. return array('url'=>$thumburl,'path'=>$thumbname);
  240. }
  241. }
  242. else
  243. {
  244. // 缩略图尺寸
  245. $width = (int)($srcWidth*$scale);
  246. $height = (int)($srcHeight*$scale);
  247. }
  248. // 载入原图
  249. $createFun = 'imagecreatefrom'.($type=='jpg'?'jpeg':$type);
  250. if(!function_exists($createFun))
  251. $createFun = 'imagecreatefromjpeg';
  252. $srcImg = $createFun($image);
  253. $x = 0;
  254. $y = 0;
  255. $width = $maxWidth;
  256. $height = $maxHeight;
  257. if($maxWidth > 0 && $maxHeight > 0)
  258. {
  259. $target_ratio = $maxWidth/$maxHeight;
  260. $img_ratio = $srcWidth/$srcHeight;
  261. if($gen==2)
  262. {
  263. if ($target_ratio > $img_ratio) {
  264. $width = $maxWidth;
  265. $height = $img_ratio * $maxHeight;
  266. $x = ($srcWidth - ($target_ratio * $height)) / 2;
  267. $y = 0;
  268. } else {
  269. $width = $maxWidth;
  270. $height = $maxWidth / $img_ratio;
  271. $x = 0;
  272. $y = ($srcHeight - ( (1 / $target_ratio) * $srcWidth)) / 2;
  273. }
  274. }
  275. else{
  276. if ($target_ratio > $img_ratio) {
  277. $height = $maxWidth;
  278. $width = $img_ratio * $maxHeight;
  279. } else {
  280. $height = $maxWidth / $img_ratio;
  281. $width = $maxWidth;
  282. }
  283. if ($height > $maxHeight) {
  284. $height = $maxHeight;
  285. }
  286. if ($width > $maxWidth) {
  287. $height = $maxWidth;
  288. }
  289. }
  290. if($gen==1){
  291. //创建缩略图
  292. if($type!='gif' && function_exists('imagecreatetruecolor'))
  293. $thumbImg = imagecreatetruecolor($maxWidth, $maxHeight);
  294. else
  295. $thumbImg = imagecreate($maxWidth, $maxHeight);
  296. $bgcolor = "ffffff";
  297. sscanf($bgcolor, "%2x%2x%2x", $red, $green, $blue);
  298. $white = imagecolorallocate($thumbImg, $red, $green, $blue);
  299. imagefilledrectangle($thumbImg, 0, 0, $maxWidth, $maxHeight, $white);
  300. }
  301. else{
  302. //创建缩略图
  303. if($type!='gif' && function_exists('imagecreatetruecolor'))
  304. $thumbImg = imagecreatetruecolor($width, $height);
  305. else
  306. $thumbImg = imagecreate($width, $height);
  307. $white = imagecolorallocate($thumbImg, 0, 0, 0);
  308. imagefilledrectangle($thumbImg, 0, 0, $width, $height, $white);
  309. }
  310. }
  311. if($type!='gif' && function_exists('imagecreatetruecolor')){
  312. $cropped_image = imagecreatetruecolor($width, $height);
  313. }
  314. else{
  315. $cropped_image = imagecreate($width, $height);
  316. }
  317. // 复制图片
  318. if(function_exists("imagecopyresampled")){
  319. if($gen == 1)
  320. imagecopyresampled($thumbImg, $srcImg, ($maxWidth-$width)/2, ($maxHeight-$height)/2, 0, 0, $width, $height, $srcWidth, $srcHeight);
  321. elseif($gen == 2){
  322. imagecopyresampled($thumbImg, $srcImg, 0, 0, $x, $y, $maxWidth, $maxHeight, $width, $height);
  323. }
  324. else
  325. imagecopyresampled($thumbImg, $srcImg,0, 0, 0, 0, $width, $height, $srcWidth, $srcHeight);
  326. }
  327. else
  328. imagecopyresized($thumbImg, $cropped_image, 0, 0, 0, 0, $maxWidth, $maxHeight, $width,$height);
  329. if('gif'==$type || 'png'==$type) {
  330. $background_color = imagecolorallocate($thumbImg, 0,255,0); // 指派一个绿色
  331. imagecolortransparent($thumbImg,$background_color); // 设置为透明色,若注释掉该行则输出绿色的图
  332. }
  333. // 对jpeg图形设置隔行扫描
  334. if('jpg'==$type || 'jpeg'==$type)
  335. imageinterlace($thumbImg,$interlace);
  336. // 生成图片
  337. imagejpeg($thumbImg,$thumbname,100);
  338. imagedestroy($thumbImg);
  339. imagedestroy($srcImg);
  340. imagedestroy($cropped_image);
  341. return array('url'=>$thumburl,'path'=>$thumbname);
  342. }
  343. return false;
  344. }
  345. public function make_thumb($srcImg,$srcWidth,$srcHeight,$type,$maxWidth=200,$maxHeight=50,$gen = 0)
  346. {
  347. $interlace = $interlace? 1:0;
  348. if($maxWidth > 0 && $maxHeight > 0)
  349. $scale = min($maxWidth/$srcWidth, $maxHeight/$srcHeight); // 计算缩放比例
  350. elseif($maxWidth == 0)
  351. $scale = $maxHeight/$srcHeight;
  352. elseif($maxHeight == 0)
  353. $scale = $maxWidth/$srcWidth;
  354. if($scale >= 1)
  355. {
  356. // 超过原图大小不再缩略
  357. $width = $srcWidth;
  358. $height = $srcHeight;
  359. }
  360. else
  361. {
  362. // 缩略图尺寸
  363. $width = (int)($srcWidth*$scale);
  364. $height = (int)($srcHeight*$scale);
  365. }
  366. if($gen == 1)
  367. {
  368. $width = $maxWidth;
  369. $height = $maxHeight;
  370. }
  371. //创建缩略图
  372. if($type!='gif' && function_exists('imagecreatetruecolor'))
  373. $thumbImg = imagecreatetruecolor($width, $height);
  374. else
  375. $thumbImg = imagecreatetruecolor($width, $height);
  376. $x = 0;
  377. $y = 0;
  378. if($gen == 1 && $maxWidth > 0 && $maxHeight > 0)
  379. {
  380. $resize_ratio = $maxWidth/$maxHeight;
  381. $src_ratio = $srcWidth/$srcHeight;
  382. if($src_ratio >= $resize_ratio)
  383. {
  384. $x = ($srcWidth - ($resize_ratio * $srcHeight)) / 2;
  385. $width = ($height * $srcWidth) / $srcHeight;
  386. }
  387. else
  388. {
  389. $y = ($srcHeight - ( (1 / $resize_ratio) * $srcWidth)) / 2;
  390. $height = ($width * $srcHeight) / $srcWidth;
  391. }
  392. }
  393. // 复制图片
  394. if(function_exists("imagecopyresampled"))
  395. imagecopyresampled($thumbImg, $srcImg, 0, 0, $x, $y, $width, $height, $srcWidth,$srcHeight);
  396. else
  397. imagecopyresized($thumbImg, $srcImg, 0, 0, $x, $y, $width, $height, $srcWidth,$srcHeight);
  398. if('gif'==$type || 'png'==$type) {
  399. $background_color = imagecolorallocate($thumbImg, 255,255,255); // 指派一个绿色
  400. imagecolortransparent($thumbImg,$background_color); // 设置为透明色,若注释掉该行则输出绿色的图
  401. }
  402. // 对jpeg图形设置隔行扫描
  403. if('jpg'==$type || 'jpeg'==$type)
  404. imageinterlace($thumbImg,$interlace);
  405. return $thumbImg;
  406. }
  407. public function water($source,$water,$alpha=80,$position="0")
  408. {
  409. //检查文件是否存在
  410. if(!file_exists($source)||!file_exists($water))
  411. return false;
  412. //图片信息
  413. $sInfo = es_imagecls::getImageInfo($source);
  414. $wInfo = es_imagecls::getImageInfo($water);
  415. //如果图片小于水印图片,不生成图片
  416. if($sInfo["0"] < $wInfo["0"] || $sInfo['1'] < $wInfo['1'])
  417. return false;
  418. if(is_animated_gif($source))
  419. {
  420. require_once APP_ROOT_PATH."system/utils/gif_encoder.php";
  421. require_once APP_ROOT_PATH."system/utils/gif_reader.php";
  422. $gif = new GIFReader();
  423. $gif->load($source);
  424. foreach($gif->IMGS['frames'] as $k=>$img)
  425. {
  426. $im = imagecreatefromstring($gif->getgif($k));
  427. //为im加水印
  428. $sImage=$im;
  429. $wCreateFun="imagecreatefrom".$wInfo['type'];
  430. if(!function_exists($wCreateFun))
  431. $wCreateFun = 'imagecreatefromjpeg';
  432. $wImage=$wCreateFun($water);
  433. //设定图像的混色模式
  434. imagealphablending($wImage, true);
  435. switch (intval($position))
  436. {
  437. case 0: break;
  438. //左上
  439. case 1:
  440. $posY=0;
  441. $posX=0;
  442. //生成混合图像
  443. imagecopymerge($sImage, $wImage, $posX, $posY, 0, 0, $wInfo[0],$wInfo[1],$alpha);
  444. break;
  445. //右上
  446. case 2:
  447. $posY=0;
  448. $posX=$sInfo[0]-$wInfo[0];
  449. //生成混合图像
  450. imagecopymerge($sImage, $wImage, $posX, $posY, 0, 0, $wInfo[0],$wInfo[1],$alpha);
  451. break;
  452. //左下
  453. case 3:
  454. $posY=$sInfo[1]-$wInfo[1];
  455. $posX=0;
  456. //生成混合图像
  457. imagecopymerge($sImage, $wImage, $posX, $posY, 0, 0, $wInfo[0],$wInfo[1],$alpha);
  458. break;
  459. //右下
  460. case 4:
  461. $posY=$sInfo[1]-$wInfo[1];
  462. $posX=$sInfo[0]-$wInfo[0];
  463. //生成混合图像
  464. imagecopymerge($sImage, $wImage, $posX, $posY, 0, 0, $wInfo[0],$wInfo[1],$alpha);
  465. break;
  466. //居中
  467. case 5:
  468. $posY=$sInfo[1]/2-$wInfo[1]/2;
  469. $posX=$sInfo[0]/2-$wInfo[0]/2;
  470. //生成混合图像
  471. imagecopymerge($sImage, $wImage, $posX, $posY, 0, 0, $wInfo[0],$wInfo[1],$alpha);
  472. break;
  473. }
  474. //end im加水印
  475. ob_start();
  476. imagegif($sImage);
  477. $content = ob_get_contents();
  478. ob_end_clean();
  479. $frames [ ] = $content;
  480. $framed [ ] = $img['frameDelay'];
  481. }
  482. $gif_maker = new GIFEncoder (
  483. $frames,
  484. $framed,
  485. 0,
  486. 2,
  487. 0, 0, 0,
  488. "bin" //bin为二进制 url为地址
  489. );
  490. $image_rs = $gif_maker->GetAnimation ( );
  491. //如果没有给出保存文件名,默认为原图像名
  492. @unlink($source);
  493. //保存图像
  494. file_put_contents($source,$image_rs);
  495. return true;
  496. }
  497. //建立图像
  498. $sCreateFun="imagecreatefrom".$sInfo['type'];
  499. if(!function_exists($sCreateFun))
  500. $sCreateFun = 'imagecreatefromjpeg';
  501. $sImage=$sCreateFun($source);
  502. $wCreateFun="imagecreatefrom".$wInfo['type'];
  503. if(!function_exists($wCreateFun))
  504. $wCreateFun = 'imagecreatefromjpeg';
  505. $wImage=$wCreateFun($water);
  506. //设定图像的混色模式
  507. imagealphablending($wImage, true);
  508. switch (intval($position))
  509. {
  510. case 0: break;
  511. //左上
  512. case 1:
  513. $posY=0;
  514. $posX=0;
  515. //生成混合图像
  516. imagecopymerge($sImage, $wImage, $posX, $posY, 0, 0, $wInfo[0],$wInfo[1],$alpha);
  517. break;
  518. //右上
  519. case 2:
  520. $posY=0;
  521. $posX=$sInfo[0]-$wInfo[0];
  522. //生成混合图像
  523. imagecopymerge($sImage, $wImage, $posX, $posY, 0, 0, $wInfo[0],$wInfo[1],$alpha);
  524. break;
  525. //左下
  526. case 3:
  527. $posY=$sInfo[1]-$wInfo[1];
  528. $posX=0;
  529. //生成混合图像
  530. imagecopymerge($sImage, $wImage, $posX, $posY, 0, 0, $wInfo[0],$wInfo[1],$alpha);
  531. break;
  532. //右下
  533. case 4:
  534. $posY=$sInfo[1]-$wInfo[1];
  535. $posX=$sInfo[0]-$wInfo[0];
  536. //生成混合图像
  537. imagecopymerge($sImage, $wImage, $posX, $posY, 0, 0, $wInfo[0],$wInfo[1],$alpha);
  538. break;
  539. //居中
  540. case 5:
  541. $posY=$sInfo[1]/2-$wInfo[1]/2;
  542. $posX=$sInfo[0]/2-$wInfo[0]/2;
  543. //生成混合图像
  544. imagecopymerge($sImage, $wImage, $posX, $posY, 0, 0, $wInfo[0],$wInfo[1],$alpha);
  545. break;
  546. }
  547. //如果没有给出保存文件名,默认为原图像名
  548. @unlink($source);
  549. //保存图像
  550. imagejpeg($sImage,$source,100);
  551. imagedestroy($sImage);
  552. }
  553. }
  554. if(!function_exists('image_type_to_extension'))
  555. {
  556. function image_type_to_extension($imagetype)
  557. {
  558. if(empty($imagetype))
  559. return false;
  560. switch($imagetype)
  561. {
  562. case IMAGETYPE_GIF : return '.gif';
  563. case IMAGETYPE_JPEG : return '.jpeg';
  564. case IMAGETYPE_PNG : return '.png';
  565. case IMAGETYPE_SWF : return '.swf';
  566. case IMAGETYPE_PSD : return '.psd';
  567. case IMAGETYPE_BMP : return '.bmp';
  568. case IMAGETYPE_TIFF_II : return '.tiff';
  569. case IMAGETYPE_TIFF_MM : return '.tiff';
  570. case IMAGETYPE_JPC : return '.jpc';
  571. case IMAGETYPE_JP2 : return '.jp2';
  572. case IMAGETYPE_JPX : return '.jpf';
  573. case IMAGETYPE_JB2 : return '.jb2';
  574. case IMAGETYPE_SWC : return '.swc';
  575. case IMAGETYPE_IFF : return '.aiff';
  576. case IMAGETYPE_WBMP : return '.wbmp';
  577. case IMAGETYPE_XBM : return '.xbm';
  578. default : return false;
  579. }
  580. }
  581. }
  582. ?>