ここの情報は古いです。ご理解頂いた上でお取り扱いください。

source: OpenPNE/branches/work/ebihara/prj_renew_OpenPNE_Img/webapp/lib/OpenPNE/Img/Generator.php @ 6927

Last change on this file since 6927 was 6927, checked in by ebihara, 12 years ago

createCacheFromRawImage() で createCache() と同様の処理をべた書きしていたところを、 createCache() をコールするように書き換え

File size: 9.6 KB
Line 
1<?php
2/**
3 * @copyright 2005-2008 OpenPNE Project
4 * @license   http://www.php.net/license/3_01.txt PHP License 3.01
5 */
6
7/**
8 * OpenPNEで画像処理をおこなうGeneratorのスーパークラス
9 *
10 * @package OpenPNE
11 * @author Kousuke Ebihara <ebihara@tejimaya.net>
12 */
13class OpenPNE_Img_Generator
14{
15    var $jpeg_quality = 75;
16    var $width = 0;
17    var $height = 0;
18
19    var $source_format;
20    var $output_format = 'jpg';
21
22    var $cache_dir;
23    var $cache_fullpath;
24
25    /**
26     * 変換を許可する画像サイズ
27     *
28     * この配列にあるサイズの画像のみ出力できる。
29     * 空の場合は無制限となる。
30     *
31     * @var array
32     */
33    var $allowed_size;
34
35    function OpenPNE_Img_Generator($options = array())
36    {
37        $this->allowed_size = (array)$GLOBALS['_OPENPNE_IMG_ALLOWED_SIZE'];
38        if (isset($options['allowed_size'])) {
39            $this->allowed_size = $options['allowed_size'];
40        }
41
42        if (!empty($options['jpeg_quality'])) {
43            $this->jpeg_quality = $options['jpeg_quality'];
44        }
45
46        if (!empty($options['cache_dir'])) {
47            $this->cache_dir = $options['cache_dir'];
48        }
49    }
50
51    function createImage($raw_img)
52    {
53        if (!$this->isAllowedSize($this->width, $this->height)) {
54            return false;
55        }
56
57        if (!$this->isResizeImage($this->width, $this->height) && !$this->isConvertFormat()) {
58            $this->createCacheFromRawImage($raw_img);
59            return true;
60        }
61
62        // create a GD image from raw_img
63        if (!$source_gdimg  = imagecreatefromstring($raw_img)) {
64            return false;
65        }
66
67        if ($this->getOutputFormat() == 'jpg') {
68            // JPEGの場合、携帯対応
69            imageinterlace($source_gdimg, 0);
70        }
71
72        // リサイズ
73        $output_img = $this->resizeImage($source_gdimg);
74
75        // キャッシュを生成
76        $this->createCacheSubdir($this->cache_dir);
77        if ($output_img) {
78            $this->createCache($output_img);
79        } else {
80            $this->createCacheFromRawImage($raw_img);
81        }
82
83        return true;
84    }
85
86    /**
87     * GDイメージのリサイズ+形式変換
88     *
89     * @param resource $gdimg source GD image
90     * @return resource output GD image
91     */
92    function resizeImage($source_gdimg)
93    {
94        $s_width  = imagesx($source_gdimg);
95        $s_height = imagesy($source_gdimg);
96
97        $o_width  = $this->width;
98        $o_height = $this->height;
99        if (!$o_width) {
100            $o_width = $s_width;
101        }
102        if (!$o_height) {
103            $o_height = $s_height;
104        }
105
106        $this->calcResizedImageSize($o_width, $o_height, $s_width, $s_height);
107
108        if (!$this->isResizeImage($o_width, $o_height, $s_width, $s_height)) {
109            if ($this->isConvertFormat()) {
110                return $source_gdimg;
111            }
112            return false;
113        }
114
115        $output_gdimg = imagecreatetruecolor($o_width, $o_height);
116        $this->setTransparentToOutputImage($output_gdimg, $source_gdimg);
117        imagecopyresampled($output_gdimg, $source_gdimg,
118                0, 0, 0, 0, $o_width, $o_height, $s_width, $s_height);
119
120        return $output_gdimg;
121    }
122
123    function createCacheFromRawImage($raw_img)
124    {
125        if ($this->getOutputFormat() == 'png') {
126            $this->createCache($raw_img);
127        } else {
128            $handle = fopen($this->cache_fullpath, 'wb');
129            fwrite($handle, $raw_img);
130            fclose($handle);
131        }
132    }
133
134    function createCache($output_gdimg)
135    {
136        touch($this->cache_fullpath);
137        switch ($this->getOutputFormat()) {
138        case 'jpeg':
139        case 'jpg':
140        default:
141            imagejpeg($output_gdimg, $this->cache_fullpath, $this->jpeg_quality); break;
142        case 'gif':
143            imagegif($output_gdimg, $this->cache_fullpath);
144            break;
145        case 'png':
146            imagepng($output_gdimg, $this->cache_fullpath);
147            break;
148        }
149    }
150
151    function createCacheSubdir($cache_dir)
152    {
153        $subdir = dirname($this->cache_fullpath);
154        if (!is_dir($subdir)) {
155            // mkdir recursive
156            $_dir = $cache_dir;
157            if (!is_dir($_dir) && !mkdir($_dir)) {
158                return false;
159            }
160            $relative_path = substr($subdir, strlen($cache_dir)+1);
161            $parts = explode('/', $relative_path);
162            foreach ($parts as $part) {
163                $_dir .=  '/' . $part;
164                if (!is_dir($_dir) && !mkdir($_dir)) {
165                    return false;
166                }
167            }
168        }
169    }
170
171    function checkFormatString($string)
172    {
173        $string = strtolower($string);
174
175        $format = 'jpg';
176        if ($string == 'gif' || $string == 'png') {
177            $format = $string;
178        }
179       
180        return $format;
181    }
182
183    function setCacheFileName($filename)
184    {
185        $pieces = explode('.', $filename);
186        $this->setSourceFormat($this->checkFormatString(array_pop($pieces)));
187
188        $this->cache_fullpath =
189                 $this->cache_dir . '/' .
190                 $this->getCachePath($filename, $this->width, $this->height, $this->getOutputFormat());
191    }
192
193    function setOutputFormat($output_format = '')
194    {
195        if ($output_format) {
196            $this->output_format = $this->checkFormatString($output_format);
197        } else {
198            $this->output_format = $this->checkFormatString($this->getSourceFormat());
199        }
200    }
201
202    /**
203     * ファイルの高さ・幅をセット
204     *
205     * @param int $width
206     * @param int $height
207     */
208    function setImageSize($width = 0, $height = 0)
209    {
210        if (is_numeric($width)) {
211            $this->width = $width;
212        }
213
214        if (is_numeric($height)) {
215            $this->height = $height;
216        }
217    }
218
219    function setSourceFormat($source_format)
220    {
221        $this->source_format = $source_format;
222    }
223
224    function getOutputFormat()
225    {
226        return $this->output_format;
227    }
228
229    function getSourceFormat()
230    {
231        return $this->source_format;
232    }
233
234    function getCacheFullpath()
235    {
236        return $this->cache_fullpath;
237    }
238
239    function getCachePath($filename, $w, $h, $f)
240    {
241        $prefix = OPENPNE_IMG_CACHE_PREFIX;
242
243        if (!$w) $w = '';
244        if (!$h) $h = '';
245        $file = str_replace('.', '_', $filename) . '.' . $f;
246
247        $path = "{$f}/w{$w}_h{$h}/{$prefix}{$file}";
248        return $path;
249    }
250
251    function isCacheReadable()
252    {
253        return is_readable($this->cache_fullpath);
254    }
255
256    /**
257     * 変換可能な画像サイズかどうか
258     *
259     * @param int $width
260     * @param int $height
261     * @return bool
262     */
263    function isAllowedSize($width = 0, $height = 0)
264    {
265        if (!$width && !$height) {
266            return true;
267        }
268
269        $size = sprintf('%dx%d', $width, $height);
270        if ($this->allowed_size && !in_array($size, $this->allowed_size)) {
271            return false;
272        }
273
274        return true;
275    }
276
277    /**
278     * 画像フォーマットの変換をおこなうかどうか
279     *
280     * @return bool
281     */
282    function isConvertFormat()
283    {
284        if ($this->getSourceFormat() != $this->getOutputFormat()) {
285            return true;
286        }
287
288        return false;
289    }
290
291    /**
292     * 画像のリサイズをおこなうかどうか
293     *
294     * @return bool
295     */
296    function isResizeImage($o_width = 0, $o_height = 0, $s_width = 0, $s_height = 0)
297    {
298        if (!$o_width && !$o_height) {
299            return false;
300        }
301
302        if (!$s_width || !$s_height) {
303            return true;
304        }
305
306        if ($s_width <= $o_width && $s_height <= $o_height) {
307            return false;
308        }
309
310        return true;
311    }
312
313    /**
314     * リサイズ後の画像サイズを算出する
315     */
316    function calcResizedImageSize(&$o_width, &$o_height, $s_width, $s_height)
317    {
318        $h = $s_height;
319        if ($o_width < $s_width) {
320            $h = $s_height * $o_width / $s_width;
321        }
322        if ($o_height < $h && $o_height < $s_height) {
323            $o_width = $s_width * $o_height / $s_height;
324        }
325
326        if ($o_height < 1.) {
327            $o_height = 1;
328        }
329        if ($o_width < 1.) {
330            $o_width = 1;
331        }
332    }
333
334    /**
335     * 入力画像から取得した透過情報を出力画像に適用する
336     */
337    function setTransparentToOutputImage(&$output_gdimg, &$source_gdimg)
338    {
339        if ($this->getOutputFormat() != 'gif' && $this->getOutputFormat() != 'png') {
340            return null;
341        }
342
343        $trnprt_idx_s = imagecolortransparent($source_gdimg);
344        if ($trnprt_idx_s >= 0) { // 透過色が設定されている
345            imagetruecolortopalette($output_gdimg, true, 256);
346
347            // 入力画像から透明色取得
348            $trnprt_color = imagecolorsforindex($source_gdimg, $trnprt_idx_s);
349
350            // 出力画像に透明色設定
351            imagecolorset($source_gdimg, 0, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
352            imagefill($output_gdimg, 0, 0, 0);
353            imagecolortransparent($output_gdimg, 0);
354        } elseif ($this->getOutputFormat() == 'png') {  // PNG-24
355            // アルファチャンネル情報を保存するには、アルファブレンディングを解除する必要がある
356            imagealphablending($output_gdimg, false);
357            imagesavealpha($output_gdimg, true);
358
359            // 透過色設定
360            $color = imagecolorallocatealpha($output_gdimg, 0, 0, 0, 127);
361            imagefill($output_gdimg, 0, 0, $color);
362        }
363    }
364}
365
366?>
Note: See TracBrowser for help on using the repository browser.