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

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

Last change on this file since 6848 was 6848, checked in by ebihara, 13 years ago

元クラスのresize_img()で参照してたプロパティを削除

File size: 10.1 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// リファクタリングのため、一時的にスーパークラスをインクルード
8require_once 'OpenPNE/Img/Generator.php';
9require_once 'OpenPNE/Img/Storage.php';
10
11class OpenPNE_Img
12{
13    /**
14     * Request Parameters
15     * @var array
16     *     - w : width
17     *     - h : height
18     *     - f : format
19     *     - filename : image filename
20     */
21    var $requests;
22
23    // options
24    var $dsn;
25    var $cache_dir;
26    var $jpeg_quality = 75;
27
28    var $raw_img;
29
30    var $source_filename;
31
32    var $cache_fullpath;
33
34    var $generator;
35    var $storage;
36
37    /**
38     * constructor
39     * set options
40     *
41     * @access public
42     * @param array $options
43     */
44    function OpenPNE_Img($options = array())
45    {
46        foreach ($options as $key => $value) {
47            switch ($key) {
48            case 'dsn':
49                $this->dsn = $value;
50                break;
51            case 'jpeg_quality':
52                $this->jpeg_quality = intval($value);
53                break;
54            case 'cache_dir':
55                $this->cache_dir = realpath($value);
56                break;
57            }
58        }
59
60        $this->generator = new OpenPNE_Img_Generator();
61        $this->storage = new OpenPNE_Img_Storage();
62    }
63
64    /**
65     * リクエストパラメータを取得
66     *
67     * @access public
68     * @param array $vars request vars
69     */
70    function set_requests($vars)
71    {
72        // initialize
73        $this->requests = array(
74            'w' => 0,
75            'h' => 0,
76            'f' => '',
77            'filename' => '',
78        );
79
80        foreach ($vars as $key => $value) {
81            switch ($key) {
82            case 'w':
83            case 'h':
84                if (is_numeric($value)) {
85                    $this->requests[$key] = intval($value);
86                }
87                break;
88            case 'f':
89                $allowed_format = array('jpg', 'jpeg', 'gif', 'png');
90                if (in_array(strtolower($value), $allowed_format)) {
91                    $this->requests[$key] = strtolower($value);
92                }
93                break;
94            case 'filename':
95                if (!preg_match('/[^\.\w]/', $value)) {
96                    $this->requests[$key] = $value;
97                }
98                break;
99            }
100        }
101    }
102
103    /**
104     * 画像を生成
105     *
106     * @access public
107     */
108    function generate_img()
109    {
110        if (!$this->requests['filename']) {
111            return false;
112        }
113
114        // 解像度のチェック
115        $w = $this->requests['w'];
116        $h = $this->requests['h'];
117        if ($w || $h) {
118            $size = sprintf('%dx%d', $w, $h);
119            $allowed_size = (array)$GLOBALS['_OPENPNE_IMG_ALLOWED_SIZE'];
120            if ($allowed_size && !in_array($size, $allowed_size)) {
121                return false;
122            }
123        }
124
125        $this->set_source_filename();
126        $this->set_output_format();
127        $this->set_cache_filename();
128
129        if ($this->check_cache()) {
130            return true;
131        }
132
133        if (!$this->raw_img = $this->get_raw_img()) {
134            return false;
135        }
136
137        // サイズ指定がなく、かつ、形式変換しない場合(GDに変換する必要なし)
138        if (!$w && !$h && ($this->generator->getSourceFormat() == $this->generator->getOutputFormat())) {
139            $this->create_cache_from_raw_img();
140            return true;
141        }
142
143        // create a GD image from raw_img
144        if (!$source_gdimg  = imagecreatefromstring($this->raw_img)) {
145            return false;
146        }
147
148        if ($this->requests['f'] == 'jpg') {
149            // JPEGの場合、携帯対応
150            imageinterlace($source_gdimg, 0);
151        }
152
153        //リサイズ
154        $output_img = $this->resize_img($source_gdimg, $w, $h);
155
156        //キャッシュを生成
157        if ($output_img) {
158            $this->create_cache($output_img);
159        } else {
160            $this->create_cache_from_raw_img();
161        }
162
163        return true;
164    }
165
166    /**
167     * 画像を出力
168     *
169     * @access public
170     */
171    function output_img()
172    {
173        $this->send_content_type();
174
175        if ($mtime = filemtime($this->cache_fullpath)) {
176            // Etag
177            include_once 'Etag.php';
178            $etag = new Etag($this->cache_fullpath.$mtime, $mtime);
179            if ($etag->etagCheck()) {
180                exit;
181            }
182        }
183        @readfile($this->cache_fullpath);
184    }
185
186    /**
187     * キャッシュが残っているかどうかチェックする
188     *
189     * @access protected
190     * @return boolean
191     */
192    function check_cache()
193    {
194        return is_readable($this->cache_fullpath);
195    }
196
197    /**
198     * 画像データを取得
199     *
200     * @access protected
201     * @return string raw image data
202     */
203    function get_raw_img()
204    {
205        return $this->get_raw_img4db();
206    }
207
208    /**
209     * DBから画像バイナリを取得
210     *
211     * @access protected
212     */
213    function get_raw_img4db()
214    {
215        include_once 'OpenPNE/DB.php';
216        $db =& new OpenPNE_DB($this->dsn);
217
218        $sql = 'SELECT bin, type FROM c_image WHERE filename = ?';
219        $params = array($this->requests['filename']);
220
221        if ($c_image = $db->get_row($sql, $params)) {
222            if ($c_image['type']) {
223                $this->generator->setSourceFormat($c_image['type']);
224            }
225            return base64_decode($c_image['bin']);
226        } else {
227            return false;
228        }
229    }
230
231    /**
232     * GDイメージのリサイズ+形式変換
233     *
234     * @access protected
235     * @param resource $gdimg source GD image
236     * @param int $w width
237     * @param int $h height
238     * @return resource output GD image
239     */
240    function resize_img($source_gdimg, $w, $h)
241    {
242        return $this->generator->resizeImage($source_gdimg, $w, $h);
243    }
244
245    /**
246     * send "Content-Type" header
247     *
248     * @access protected
249     */
250    function send_content_type()
251    {
252        switch ($this->generator->getOutputFormat()) {
253        case 'jpeg':
254        case 'jpg':
255        default:
256            header('Content-type: image/jpeg');
257            break;
258        case 'gif':
259            header('Content-type: image/gif');
260            break;
261        case 'png':
262            header('Content-type: image/png');
263            break;
264        }
265    }
266
267    /**
268     * キャッシュを作成する
269     *
270     * @access protected
271     */
272    function create_cache($output_gdimg)
273    {
274        $this->create_cache_subdir();
275
276        touch($this->cache_fullpath);
277        switch ($this->generator->getOutputFormat()) {
278        case 'jpeg':
279        case 'jpg':
280        default:
281            imagejpeg($output_gdimg, $this->cache_fullpath, $this->jpeg_quality);
282            break;
283        case 'gif':
284            imagegif($output_gdimg, $this->cache_fullpath);
285            break;
286        case 'png':
287            imagepng($output_gdimg, $this->cache_fullpath);
288            break;
289        }
290    }
291
292    /**
293     * @access protected
294     */
295    function create_cache_from_raw_img()
296    {
297        $this->create_cache_subdir();
298
299        if ($this->generator->getOutputFormat() == 'png') {
300            touch($this->cache_fullpath);
301            $output_gdimg = imagecreatefromstring($this->raw_img);
302            imagepng($output_gdimg, $this->cache_fullpath);
303        } else {
304            $handle = fopen($this->cache_fullpath, 'wb');
305            fwrite($handle, $this->raw_img);
306            fclose($handle);
307        }
308    }
309
310    /**
311     * キャッシュ用サブディレクトリの作成
312     * @access protected
313     */
314    function create_cache_subdir()
315    {
316        $subdir = dirname($this->cache_fullpath);
317        if (!is_dir($subdir)) {
318            // mkdir recursive
319            $_dir = $this->cache_dir;
320            if (!is_dir($_dir) && !mkdir($_dir)) {
321                return false;
322            }
323            $relative_path = substr($subdir, strlen($this->cache_dir)+1);
324            $parts = explode('/', $relative_path);
325            foreach ($parts as $part) {
326                $_dir .=  '/' . $part;
327                if (!is_dir($_dir) && !mkdir($_dir)) {
328                    return false;
329                }
330            }
331        }
332    }
333
334    /**
335     * ソースファイル名(拡張子からフォーマットも)設定
336     * @access protected
337     */
338    function set_source_filename()
339    {
340        if ($this->requests['filename']) {
341            //DBから取得する場合
342            $this->source_filename = $this->requests['filename'];
343        }
344
345        $pieces = explode('.', $this->source_filename);
346        $this->generator->setSourceFormat($this->check_format(array_pop($pieces)));
347    }
348
349    /**
350     * @access protected
351     */
352    function set_output_format()
353    {
354        if ($this->requests['f']) {
355            // リクエストの f(ormat)に従う
356            $format = $this->check_format($this->requests['f']);
357        } else {
358            // ソースに従う
359            $format = $this->check_format($this->generator->getSourceFormat());
360        }
361        $this->generator->setOutputFormat($format);
362    }
363
364    /**
365     * @access protected
366     */
367    function set_cache_filename()
368    {
369        $filename = $this->source_filename;
370        $w = $this->requests['w'];
371        $h = $this->requests['h'];
372        $f = $this->generator->getOutputFormat();
373
374        $this->cache_fullpath =
375                 $this->cache_dir . '/' .
376                 $this->get_cache_path($filename, $w, $h, $f);
377    }
378
379    /**
380     * @access protected
381     */
382    function check_format($string)
383    {
384        switch (strtolower($string)) {
385        case 'jpg' :
386        case 'jpeg':
387        default:
388            return 'jpg';
389        case 'gif':
390            return 'gif';
391        case 'png':
392            return 'png';
393        }
394    }
395
396    /**
397     * static
398     */
399    function get_cache_path($filename, $w, $h, $f)
400    {
401        $prefix = OPENPNE_IMG_CACHE_PREFIX;
402
403        if (!$w) $w = '';
404        if (!$h) $h = '';
405        $file = str_replace('.', '_', $filename) . '.' . $f;
406
407        $path = "{$f}/w{$w}_h{$h}/{$prefix}{$file}";
408        return $path;
409    }
410}
411
412?>
Note: See TracBrowser for help on using the repository browser.