PageRenderTime 25ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/controllers/components/thumbmake.php

https://github.com/hidetoshing/interactive_ui
PHP | 436 lines | 192 code | 96 blank | 148 comment | 26 complexity | 3af89e49286700d9684482eab6bafdba MD5 | raw file
  1. <?php
  2. /**
  3. * ThumbMake
  4. *
  5. * @author ZARU
  6. * @copyright 2008 ZARU
  7. * @license http://www.gnu.org/copyleft/lesser.html LGPL
  8. * @link http://blog.tofu-kun.org
  9. */
  10. class ThumbmakeComponent extends Object {
  11. /**
  12. * 初期化
  13. *
  14. * @return
  15. * @access public
  16. * @static
  17. */
  18. function init(){
  19. $this->setMakeType = 'gd'; //画像生成エンジンの選択 (GD/ImageMagick)
  20. $this->imageMagick = '/usr/bin/convert'; //ImageMagickのパス
  21. $this->srcPath = '';
  22. $this->dstPath = '';
  23. $this->dstName = '';
  24. $this->imageType = '';
  25. $this->dstImage = '';
  26. $this->left = 0;
  27. $this->top = 0;
  28. $this->x = 0;
  29. $this->y = 0;
  30. $this->srcWidth = 0;
  31. $this->srcHeight = 0;
  32. $this->dstWidth = 0;
  33. $this->dstHeight = 0;
  34. $this->cropWidth = 0;
  35. $this->cropHeight = 0;
  36. $this->quality = 100;
  37. $this->crop = false;
  38. }
  39. /**
  40. * 指定された画像を表示する
  41. *
  42. * @return boolean
  43. * @access public
  44. * @static
  45. */
  46. function disp() {
  47. //保存された画像を表示する
  48. if(file_exists($this->dstPath)){
  49. $source = file_get_contents($this->dstPath);
  50. $len = strlen($source);
  51. header('Content-Type: ' . $this->imageType . ';');
  52. header('Content-Length: ' . $len);
  53. header('Content-Disposition: inline; filename="' . $this->dstName .'"');
  54. echo $source;
  55. }else{
  56. return false;
  57. }
  58. }
  59. /**
  60. * 生成された画像を保存する
  61. *
  62. * @return boolean
  63. * @access public
  64. * @static
  65. */
  66. function save() {
  67. //保存先のディレクトリが存在しているかチェック
  68. $filePath = dirname($this->dstPath);
  69. if(!file_exists($filePath)){
  70. mkdir($filePath);
  71. }
  72. if($this->imageType == 'image/jpeg'){
  73. // e($this->dstImage);
  74. // e($this->dstPath);
  75. // e($this->quality);
  76. return imageJpeg($this->dstImage,$this->dstPath,$this->quality);
  77. }elseif($this->imageType == 'image/gif'){
  78. return imageGif($this->dstImage,$this->dstPath);
  79. }elseif($this->imageType == 'image/png'){
  80. return imagePng($this->dstImage,$this->dstPath);
  81. }
  82. }
  83. /**
  84. * 元画像のパスと、保存先の画像のパスをセットする
  85. *
  86. * @param string $srcPath 元画像のファイルパス
  87. * @param string $dstPath 保存先画像のファイルパス
  88. *
  89. * @return boolean
  90. * @access public
  91. * @static
  92. */
  93. function setImage($srcPath, $dstPath) {
  94. $this->init();
  95. // e($dstPath);
  96. if(file_exists($srcPath)){
  97. //画像のパスをセット
  98. $this->srcPath = $srcPath;
  99. $this->dstPath = $dstPath;
  100. //ファイルタイプと縦横サイズを取得
  101. $imageInfo = getimagesize($this->srcPath);
  102. $this->srcWidth = $imageInfo['0'];
  103. $this->srcHeight = $imageInfo['1'];
  104. $this->imageType = $imageInfo['mime'];
  105. $dstFile = explode('/',$dstPath);
  106. $this->dstName = array_pop($dstFile);
  107. return true;
  108. }else{
  109. return false;
  110. }
  111. }
  112. /**
  113. * JPEGの画質設定
  114. *
  115. * @param integer $quality JPEGの圧縮率
  116. *
  117. * @return
  118. * @access public
  119. * @static
  120. */
  121. function setQuality($quality) {
  122. $this->quality = $quality;
  123. }
  124. /**
  125. * 横幅指定、縦なりゆきリサイズ
  126. *
  127. * @param string $width 横幅指定
  128. *
  129. * @return boolean
  130. * @access public
  131. * @static
  132. */
  133. function width($width) {
  134. $this->dstWidth = $width;
  135. //比率を出して縦のpxを計算する
  136. $rate = $width / $this->srcWidth;
  137. $this->dstHeight = ceil($this->srcHeight * $rate);
  138. //横縦が出たのでリサイズする
  139. return $this->resize();
  140. }
  141. /**
  142. * 縦幅指定、横なりゆきリサイズ
  143. *
  144. * @param string $height 縦幅指定
  145. *
  146. * @return boolean
  147. * @access public
  148. * @static
  149. */
  150. function height($height) {
  151. $this->dstHeight = $height;
  152. //比率を出して縦のpxを計算する
  153. $rate = $height / $this->srcHeight;
  154. $this->dstWidth = ceil($this->srcWidth * $rate);
  155. //横縦が出たのでリサイズする
  156. return $this->resize();
  157. }
  158. /**
  159. * リサイズ&トリミング
  160. *
  161. * @param string $width 横幅指定
  162. * @param string $height 縦幅指定
  163. *
  164. * @return boolean
  165. * @access public
  166. * @static
  167. */
  168. function resizeCrop($width, $height) {
  169. //use GD
  170. if($this->setMakeType === 'gd'){
  171. $left = 0;
  172. $top = 0;
  173. $srcRate = $this->srcWidth / $this->srcHeight;
  174. $dstRate = $width / $height;
  175. if($srcRate < $dstRate){
  176. $origHeight = $this->srcHeight;
  177. $this->srcHeight = $this->srcWidth / $dstRate;
  178. $top = ($origHeight - $this->srcHeight) / 2;
  179. }elseif($srcRate > $dstRate){
  180. $origWidth = $this->srcWidth;
  181. $this->srcWidth = $this->srcHeight * $dstRate;
  182. $left = ($origWidth - $this->srcWidth) / 2;
  183. }
  184. $this->dstWidth = $width;
  185. $this->dstHeight = $height;
  186. //use ImageMagick
  187. }elseif($this->setMakeType === 'im'){
  188. //縦の方が短いので縦に合わせる
  189. if($width / $this->srcWidth <= $height / $this->srcHeight){
  190. $rate = $height / $this->srcHeight;
  191. $this->dstHeight = $height;
  192. $this->dstWidth = ceil($this->srcWidth * $rate);
  193. //切り抜き位置
  194. $left = ceil(($this->dstWidth - $width) / 2);
  195. $top = 0;
  196. //横に合わせる
  197. }else{
  198. $rate = $width / $this->srcWidth;
  199. $this->dstWidth = $width;
  200. $this->dstHeight = ceil($this->srcHeight * $rate);
  201. //切り抜き位置
  202. $top = ceil(($this->dstHeight - $height) / 2);
  203. $left = 0;
  204. }
  205. //最終トリミングサイズ
  206. $this->cropWidth = $width;
  207. $this->cropHeight = $height;
  208. }
  209. //トリミングの設定
  210. $this->crop($top, $left);
  211. //横縦が出たのでリサイズする
  212. return $this->resize();
  213. }
  214. /**
  215. * リサイズ
  216. *
  217. * @param string $width 横幅指定
  218. * @param string $height 縦幅指定
  219. *
  220. * @return boolean
  221. * @access public
  222. * @static
  223. */
  224. function resize() {
  225. /**
  226. * 元画像の比率と、リサイズ指定の比率が合わない場合、どちらかに合わせてリサイズ後
  227. * crop を使って指定のサイズにトリミングする
  228. */
  229. if($this->setMakeType === 'gd'){
  230. if($this->imageType == 'image/jpeg'){
  231. //元画像を読み込み
  232. $srcImage = imagecreatefromjpeg($this->srcPath);
  233. }elseif($this->imageType == 'image/gif'){
  234. //元画像を読み込み
  235. $srcImage = imagecreatefromgif($this->srcPath);
  236. }elseif($this->imageType == 'image/png'){
  237. //元画像を読み込み
  238. $srcImage = imagecreatefrompng($this->srcPath);
  239. }
  240. //リサイズ用の画像を作成
  241. $this->dstImage = imagecreatetruecolor($this->dstWidth, $this->dstHeight);
  242. // e($this->dstImage)."###";
  243. //白色に塗りつぶし
  244. $white = imagecolorallocate($this->dstImage, 255, 255, 255);
  245. imagefill($this->dstImage, 0, 0, $white);
  246. //元画像からリサイズしてコピー
  247. imagecopyresampled($this->dstImage, $srcImage, $this->x, $this->y, $this->left, $this->top,
  248. $this->dstWidth, $this->dstHeight, $this->srcWidth, $this->srcHeight);
  249. //画像を保存
  250. return $this->save();
  251. }elseif($this->setMakeType === 'im'){
  252. //縮小
  253. $param = ' -resize ';
  254. $param .= $this->dstWidth . 'x' . $this->dstHeight . ' ';
  255. //トリミング設定がされていた場合
  256. if($this->crop){
  257. $param .= ' -crop ';
  258. $param .= $this->cropWidth . 'x' . $this->cropHeight;
  259. $param .= '+' . $this->left . '+' . $this->top . ' ';
  260. //余白設定がされていた場合、ボーダーをつける
  261. if($this->x != 0 || $this->y != 0){
  262. $param .= ' -border ';
  263. $param .= $this->x . 'x' . $this->y;
  264. $param .= ' -bordercolor white ';
  265. }
  266. }
  267. $param .= $this->srcPath . ' ' . $this->dstPath;
  268. $dump = exec($this->imageMagick . $param);
  269. if($dump == ''){
  270. return true;
  271. }else{
  272. return false;
  273. }
  274. }
  275. }
  276. /**
  277. * トリミングの設定
  278. *
  279. * @param string $top 切り抜き y
  280. * @param string $$left 切り抜き x
  281. *
  282. * @return
  283. * @access public
  284. * @static
  285. */
  286. function crop($top, $left) {
  287. $this->crop = true;
  288. $this->top = $top;
  289. $this->left = $left;
  290. }
  291. /**
  292. * URLからパラメータを受け取る
  293. *
  294. * @return array
  295. * @access public
  296. * @static
  297. */
  298. function getParam($params) {
  299. //初期化
  300. $this->init();
  301. //サムネイルのwidthとheight
  302. list($width,$height) = explode('x',$params['pass']['0']);
  303. //元画像のパスを解析
  304. $count = count($params['pass']);
  305. $srcPath = array();
  306. for($i=2;$i<$count;$i++){
  307. $srcPath[] = $params['pass'][$i];
  308. if($i === ($count - 1)){
  309. $srcName = $params['pass'][$i];
  310. }else{
  311. $srcDir[] = $params['pass'][$i];
  312. }
  313. }
  314. //元画像のパス
  315. $srcDir = implode(DS,$srcDir);
  316. //元画像のファイル名から拡張子部分を取り除く
  317. if(preg_match("/^(.+)\.([^\.]+)$/",$srcName,$match)){
  318. $fileName = $match['1'];
  319. $fileExt = $match['2'];
  320. }
  321. //元画像のパス
  322. $this->srcPath = WWW_ROOT . $srcDir . DS . $fileName . '.' . $fileExt;
  323. //元画像が存在したらサムネイルのサイズを変えす
  324. if(file_exists($this->srcPath)){
  325. //サムネイルのパス
  326. $this->dstPath = WWW_ROOT . $srcDir . DS
  327. . $fileName . '_' . $params['pass']['0'] . '_' . $params['pass']['1'] . '.' . $fileExt;
  328. $this->dstName = $fileName . '_' . $params['pass']['1'] . '.' . $fileExt;
  329. //ファイルタイプと縦横サイズを取得
  330. $imageInfo = getimagesize($this->srcPath);
  331. $this->srcWidth = $imageInfo['0'];
  332. $this->srcHeight = $imageInfo['1'];
  333. $this->imageType = $imageInfo['mime'];
  334. return array($width,$height);
  335. }else{
  336. header("HTTP/1.0 404 Not Found");
  337. exit();
  338. }
  339. }
  340. }