ResizeImage.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. <?php
  2. /*  
  3. * ResizeImage.php  
  4. * 缩略图    
  5. * 更新: Jacky.Chen 2013/10/21 21:26  
  6. *  
  7. */
  8. namespace app\common\components;
  9. use Yii;
  10. class ResizeImage
  11. {
  12. //图片类型
  13. private $type;
  14. //实际宽度
  15. public $width;
  16. //实际高度
  17. public $height;
  18. //改变后的宽度
  19. private $resizeWidth;
  20. //改变后的高度
  21. private $resizeHeight;
  22. //是否裁图
  23. public $cut;//0:等比缩放 1:从左上角裁切 2:裁切中间核心内容 3: 按照目标大小,填白缩放
  24. //源图象
  25. public $srcimg;
  26. //目标图象地址
  27. public $dstimg;
  28. //临时创建的图象
  29. var $im;
  30. //是否使用缓存
  31. public $usecache;
  32. //文件名
  33. private $filename;
  34. //文件路径hash
  35. private $hash;
  36. function __construct($srcimg, $resizewidth, $resizeheight, $hash, $cut, $usecache, $dstrootdir)
  37. {
  38. dir_create($dstrootdir);
  39. if ($srcimg == '') {return false;}
  40. $this->srcimg = $srcimg;
  41. $this->resizeWidth = $resizewidth;
  42. $this->resizeHeight = $resizeheight;
  43. $this->cut = $cut;
  44. $this->usecache = $usecache;
  45. $this->hash = $hash;
  46. //图片的类型
  47. $this->type = 'jpg';//所有的缩略图都为jpg后缀
  48. //$this->type = strtolower(substr(strrchr($this->srcimg,"."),1));
  49. //目标图象地址
  50. $this -> dstImg($dstrootdir);
  51. if ($this->usecache && file_exists($this->dstimg)){
  52. return true;
  53. }
  54. else
  55. {
  56. //初始化图象
  57. $this->initImg();
  58. //尺寸
  59. $this->width = imagesx($this->im);
  60. $this->height = imagesy($this->im);
  61. //生成图象
  62. $this->newImg();
  63. ImageDestroy($this->im);
  64. }
  65. }
  66. //返回缩略图相关信息
  67. function getDstImgInfo()
  68. {
  69. $info = getimagesize($this->dstimg);
  70. $array = array('width'=>$info[0],'height'=>$info[1],'type'=>$this->type,'dstimg'=>$this->dstimg);
  71. return $array;
  72. }
  73. private function newImg()
  74. {
  75. //改变后的图象的比例
  76. $resize_ratio = ($this->resizeWidth)/($this->resizeHeight);
  77. //实际图象的比例
  78. $ratio = ($this->width)/($this->height);
  79. if(($this->cut)=="1")
  80. //裁图
  81. {
  82. if($ratio>=$resize_ratio)
  83. //高度优先
  84. {
  85. $newimg = imagecreatetruecolor($this->resizeWidth,$this->resizeHeight);
  86. $color=imagecolorallocate($newimg,255,255,255);
  87. imagecolortransparent($newimg,$color);
  88. imagefill($newimg,0,0,$color);
  89. imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, $this->resizeWidth,$this->resizeHeight, (($this->height)*$resize_ratio), $this->height);
  90. $this->createImg($newimg);
  91. }
  92. if($ratio<$resize_ratio)
  93. //宽度优先
  94. {
  95. $newimg = imagecreatetruecolor($this->resizeWidth,$this->resizeHeight);
  96. $color=imagecolorallocate($newimg,255,255,255);
  97. imagecolortransparent($newimg,$color);
  98. imagefill($newimg,0,0,$color);
  99. imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, $this->resizeWidth, $this->resizeHeight, $this->width, (($this->width)/$resize_ratio));
  100. $this->createImg($newimg);
  101. }
  102. }
  103. else if($this->cut==2)//取最核心的中间内容
  104. {
  105. if($this->width>=$this->resizeWidth)//如果原图宽度大于目标宽度
  106. {
  107. //目标偏移量
  108. $src_y = 0;
  109. $src_x = 0;
  110. //以原图比例为基础,宽度优先计算出的缩略目标图尺寸
  111. $resize_width = $this->resizeWidth;
  112. $resize_height = ceil($this->resizeWidth/$ratio);
  113. //原图以宽度优先,按照缩略图宽高比计算出的高度
  114. $cal_height = ceil($this->width/$resize_ratio);
  115. if($this->height>$cal_height)//缩略时进行位置偏移
  116. {
  117. $src_y = ceil(($this->height-$cal_height)/2);
  118. $final_height = $cal_height;
  119. $final_width= $this->width;
  120. }
  121. else//原图高度不足
  122. {
  123. $resize_height = $this->height;
  124. $resize_width = ceil($resize_height*$resize_ratio);
  125. //原图以高度优先,按照缩略图宽高比计算出的宽度
  126. $cal_width = ceil($this->height*$resize_ratio);
  127. //位置偏移
  128. $src_x = ceil(($this->width-$cal_width)/2);
  129. $final_width = $cal_width;
  130. $final_height = $this->height;
  131. }
  132. $newimg = imagecreatetruecolor($this->resizeWidth,$this->resizeHeight); imagefill($newimg, 0, 0, 0xFFFFFF);
  133. $color=imagecolorallocate($newimg,255,255,255);
  134. imagecolortransparent($newimg,$color);
  135. imagefill($newimg,0,0,$color);
  136. $dst_x = $dst_y = 0;
  137. if ($resize_width < $this->resizeWidth){$dst_x = ($this->resizeWidth-$resize_width)/2;}
  138. if ($resize_height < $this->resizeHeight){ $dst_y = ($this->resizeHeight - $resize_height)/2;}
  139. imagecopyresampled($newimg, $this->im, $dst_x, $dst_y, $src_x, $src_y, $this->resizeWidth, $this->resizeHeight,$final_width,$final_height);
  140. $this->createImg($newimg);
  141. }
  142. else
  143. {
  144. //目标偏移量
  145. $src_y = 0;
  146. $src_x = 0;
  147. if($this->height>=$this->resizeHeight)//如果原图高度大于目标高度
  148. {
  149. //以原图比例为基础,高度优先计算出的缩略目标图宽度
  150. $resize_width = ceil($this->resizeHeight*$ratio);
  151. $resize_height = $this->resizeHeight;
  152. $newimg = imagecreatetruecolor($this->resizeWidth,$this->resizeHeight);imagefill($newimg, 0, 0, 0xFFFFFF);
  153. $dst_x = $dst_y = 0;
  154. if ($resize_width < $this->resizeWidth){$dst_x = ($this->resizeWidth-$resize_width)/2;}
  155. if ($resize_height < $this->resizeHeight){ $dst_y = ($this->resizeHeight - $resize_height)/2;}
  156. imagecopyresampled($newimg, $this->im, $dst_x, $dst_y, $src_x, $src_y, $resize_width, $resize_height,$this->width,$this->height);
  157. $this->createImg($newimg);
  158. }
  159. else
  160. {
  161. $src_y = 0;
  162. $src_x = 0;
  163. $newimg = imagecreatetruecolor($this->resizeWidth,$this->resizeHeight);imagefill($newimg, 0, 0, 0xFFFFFF);
  164. $dst_x = $dst_y = 0;
  165. $resize_width = $this->width;
  166. $resize_height = $this->height;
  167. if ($resize_width < $this->resizeWidth){$dst_x = ($this->resizeWidth-$resize_width)/2;}
  168. if ($resize_height < $this->resizeHeight){ $dst_y = ($this->resizeHeight - $resize_height)/2;}
  169. imagecopyresampled($newimg, $this->im, $dst_x, $dst_y, $src_x, $src_y, $resize_width, $resize_height,$this->width,$this->height);
  170. $this->createImg($newimg);
  171. }
  172. }
  173. }
  174. else if($this->cut==3)
  175. {
  176. if($ratio>=$resize_ratio)
  177. {
  178. $newimg = imagecreatetruecolor($this->resizeWidth,($this->resizeWidth)/$ratio);
  179. $color=imagecolorallocate($newimg,255,255,255);
  180. imagecolortransparent($newimg,$color);
  181. imagefill($newimg,0,0,$color);
  182. imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, $this->resizeWidth, ($this->resizeWidth)/$ratio, $this->width, $this->height);
  183. $this->createImg($newimg);
  184. $this->srcimg = $this->dstimg;
  185. $this->initImg();
  186. $this->width = imagesx($this->im);
  187. $this->height = imagesy($this->im);
  188. $newimg = imagecreatetruecolor($this->resizeWidth,$this->resizeHeight);
  189. $whites = imagecolorallocate($newimg,255,255,255);
  190. imagefill($newimg,0,0,$whites);
  191. $dst_x = 0;
  192. $dst_y = ($this->resizeHeight-$this->height)/2;
  193. imagecopy($newimg, $this->im, $dst_x, $dst_y, 0, 0, $this->width, $this->height);
  194. $this->createImg($newimg);
  195. }
  196. if($ratio<$resize_ratio)
  197. {
  198. $newimg = imagecreatetruecolor(($this->resizeHeight)*$ratio,$this->resizeHeight);
  199. $color=imagecolorallocate($newimg,255,255,255);
  200. imagecolortransparent($newimg,$color);
  201. imagefill($newimg,0,0,$color);
  202. imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, ($this->resizeHeight)*$ratio, $this->resizeHeight, $this->width, $this->height);
  203. $this->createImg($newimg);
  204. $this->srcimg = $this->dstimg;
  205. $this->initImg();
  206. $this->width = imagesx($this->im);
  207. $this->height = imagesy($this->im);
  208. $newimg = imagecreatetruecolor($this->resizeWidth,$this->resizeHeight);
  209. $whites = imagecolorallocate($newimg,255,255,255);
  210. imagefill($newimg,0,0,$whites);
  211. $dst_x = ($this->resizeWidth-$this->width)/2;
  212. $dst_y = 0;
  213. imagecopy($newimg, $this->im, $dst_x, $dst_y, 0, 0, $this->width, $this->height);
  214. $this->createImg($newimg);
  215. }
  216. }
  217. else
  218. {
  219. if($ratio>=$resize_ratio)
  220. {
  221. $newimg = imagecreatetruecolor($this->resizeWidth,($this->resizeWidth)/$ratio);
  222. $color=imagecolorallocate($newimg,255,255,255);
  223. imagecolortransparent($newimg,$color);
  224. imagefill($newimg,0,0,$color);
  225. imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, $this->resizeWidth, ($this->resizeWidth)/$ratio, $this->width, $this->height);
  226. $this->createImg($newimg);
  227. }
  228. if($ratio<$resize_ratio)
  229. {
  230. $newimg = imagecreatetruecolor(($this->resizeHeight)*$ratio,$this->resizeHeight);
  231. $color=imagecolorallocate($newimg,255,255,255);
  232. imagecolortransparent($newimg,$color);
  233. imagefill($newimg,0,0,$color);
  234. imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, ($this->resizeHeight)*$ratio, $this->resizeHeight, $this->width, $this->height);
  235. $this->createImg($newimg);
  236. }
  237. }
  238. }
  239. //初始化图象
  240. private function initImg()
  241. {
  242. $srcInfo = getimagesize($this->srcimg);
  243. switch ($srcInfo[2])
  244. {
  245. case 1:
  246. $this->im = imagecreatefromgif($this->srcimg); break;
  247. case 2:
  248. $this->im = imagecreatefromjpeg($this->srcimg); break;
  249. case 3:
  250. $this->im = imagecreatefrompng($this->srcimg); break;
  251. case 6:
  252. $this->im = imagecreatefrombmp($this->srcimg); break;
  253. default:
  254. die('Unsupport the file type'); exit();
  255. }
  256. }
  257. //生成目标文件
  258. private function createImg(&$newimg)
  259. {
  260. $srcInfo = @getimagesize($this->srcimg);
  261. switch ($srcInfo[2])
  262. {
  263. case 1:
  264. imagegif($newimg,$this->dstimg); break;
  265. case 2:
  266. imagejpeg($newimg,$this->dstimg); break;
  267. case 3:
  268. imagepng($newimg,$this->dstimg); break;
  269. case 6:
  270. file_put_contents($this->dstimg,file_get_contents($this->srcimg)); break;
  271. default:
  272. die('unsupport file type'); exit();
  273. }
  274. imagedestroy($newimg);
  275. }
  276. //图象目标地址
  277. private function dstImg($dstrootdir)
  278. {
  279. /*
  280. *以源文件名基础,获取缩略图文件名
  281. $basename = basename($this->srcimg);
  282. $this->filename = substr($basename,strrpos($basename,DIRECTORY_SEPARATOR)+1,0-(strlen($basename)-strpos($basename,'.')));
  283. if (strlen($this->filename)<4){return false;}
  284. */
  285. $this->filename = $this->hash;
  286. if ($this->resizeWidth<=0 || $this->resizeHeight<=0){return false;}
  287. if(!empty($dstrootdir))
  288. {
  289. $this->dstimg = rtrim($dstrootdir,DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$this->resizeWidth.'_'.$this->resizeHeight.'_'.$this->filename.'.'.$this->type;
  290. }
  291. else
  292. {
  293. $this->dstimg = $this->resizeWidth.'_'.$this->resizeHeight.'_'.$this->filename.'.'.$this->type;
  294. }
  295. }
  296. }
  297. function imagecreatefrombmp($p_sFile)
  298. {
  299. $file = fopen($p_sFile,"rb");
  300. $read = fread($file,10);
  301. while(!feof($file)&&($read<>""))
  302. $read .= fread($file,1024);
  303. $temp = unpack("H*",$read);
  304. $hex = $temp[1];
  305. $header = substr($hex,0,108);
  306. if (substr($header,0,4)=="424d")
  307. {
  308. $header_parts = str_split($header,2);
  309. $width = hexdec($header_parts[19].$header_parts[18]);
  310. $height = hexdec($header_parts[23].$header_parts[22]);
  311. unset($header_parts);
  312. }
  313. $x = 0;
  314. $y = 1;
  315. $image = imagecreatetruecolor($width,$height);
  316. $body = substr($hex,108);
  317. $body_size = (strlen($body)/2);
  318. $header_size = ($width*$height);
  319. $usePadding = ($body_size>($header_size*3)+4);
  320. for ($i=0;$i<$body_size;$i+=3)
  321. {
  322. if ($x>=$width)
  323. {
  324. if ($usePadding)
  325. $i += $width%4;
  326. $x = 0;
  327. $y++;
  328. if ($y>$height)
  329. break;
  330. }
  331. $i_pos = $i*2;
  332. $r = hexdec($body[$i_pos+4].$body[$i_pos+5]);
  333. $g = hexdec($body[$i_pos+2].$body[$i_pos+3]);
  334. $b = hexdec($body[$i_pos].$body[$i_pos+1]);
  335. $color = imagecolorallocate($image,$r,$g,$b);
  336. imagesetpixel($image,$x,$height-$y,$color);
  337. $x++;
  338. }
  339. unset($body);
  340. return $image;
  341. }
  342. ?>