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

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

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

OpenPNE_Img_Generator::createCacheSubdir() のコールが createCache(), createCacheFromRawImage() 内で同様におこなわれていたのを外に出した

File size: 9.7 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            touch($this->cache_fullpath);
127            $output_gdimg = imagecreatefromstring($raw_img);
128            imagepng($output_gdimg, $this->cache_fullpath);
129        } else {
130            $handle = fopen($this->cache_fullpath, 'wb');
131            fwrite($handle, $raw_img);
132            fclose($handle);
133        }
134    }
135
136    function createCache($output_gdimg)
137    {
138        touch($this->cache_fullpath);
139        switch ($this->getOutputFormat()) {
140        case 'jpeg':
141        case 'jpg':
142        default:
143            imagejpeg($output_gdimg, $this->cache_fullpath, $this->jpeg_quality); break;
144        case 'gif':
145            imagegif($output_gdimg, $this->cache_fullpath);
146            break;
147        case 'png':
148            imagepng($output_gdimg, $this->cache_fullpath);
149            break;
150        }
151    }
152
153    function createCacheSubdir($cache_dir)
154    {
155        $subdir = dirname($this->cache_fullpath);
156        if (!is_dir($subdir)) {
157            // mkdir recursive
158            $_dir = $cache_dir;
159            if (!is_dir($_dir) && !mkdir($_dir)) {
160                return false;
161            }
162            $relative_path = substr($subdir, strlen($cache_dir)+1);
163            $parts = explode('/', $relative_path);
164            foreach ($parts as $part) {
165                $_dir .=  '/' . $part;
166                if (!is_dir($_dir) && !mkdir($_dir)) {
167                    return false;
168                }
169            }
170        }
171    }
172
173    function checkFormatString($string)
174    {
175        $string = strtolower($string);
176
177        $format = 'jpg';
178        if ($string == 'gif' || $string == 'png') {
179            $format = $string;
180        }
181       
182        return $format;
183    }
184
185    function setCacheFileName($filename)
186    {
187        $pieces = explode('.', $filename);
188        $this->setSourceFormat($this->checkFormatString(array_pop($pieces)));
189
190        $this->cache_fullpath =
191                 $this->cache_dir . '/' .
192                 $this->getCachePath($filename, $this->width, $this->height, $this->getOutputFormat());
193    }
194
195    function setOutputFormat($output_format = '')
196    {
197        if ($output_format) {
198            $this->output_format = $this->checkFormatString($output_format);
199        } else {
200            $this->output_format = $this->checkFormatString($this->getSourceFormat());
201        }
202    }
203
204    /**
205     * ファイルの高さ・幅をセット
206     *
207     * @param int $width
208     * @param int $height
209     */
210    function setImageSize($width = 0, $height = 0)
211    {
212        if (is_numeric($width)) {
213            $this->width = $width;
214        }
215
216        if (is_numeric($height)) {
217            $this->height = $height;
218        }
219    }
220
221    function setSourceFormat($source_format)
222    {
223        $this->source_format = $source_format;
224    }
225
226    function getOutputFormat()
227    {
228        return $this->output_format;
229    }
230
231    function getSourceFormat()
232    {
233        return $this->source_format;
234    }
235
236    function getCacheFullpath()
237    {
238        return $this->cache_fullpath;
239    }
240
241    function getCachePath($filename, $w, $h, $f)
242    {
243        $prefix = OPENPNE_IMG_CACHE_PREFIX;
244
245        if (!$w) $w = '';
246        if (!$h) $h = '';
247        $file = str_replace('.', '_', $filename) . '.' . $f;
248
249        $path = "{$f}/w{$w}_h{$h}/{$prefix}{$file}";
250        return $path;
251    }
252
253    function isCacheReadable()
254    {
255        return is_readable($this->cache_fullpath);
256    }
257
258    /**
259     * 変換可能な画像サイズかどうか
260     *
261     * @param int $width
262     * @param int $height
263     * @return bool
264     */
265    function isAllowedSize($width = 0, $height = 0)
266    {
267        if (!$width && !$height) {
268            return true;
269        }
270
271        $size = sprintf('%dx%d', $width, $height);
272        if ($this->allowed_size && !in_array($size, $this->allowed_size)) {
273            return false;
274        }
275
276        return true;
277    }
278
279    /**
280     * 画像フォーマットの変換をおこなうかどうか
281     *
282     * @return bool
283     */
284    function isConvertFormat()
285    {
286        if ($this->getSourceFormat() != $this->getOutputFormat()) {
287            return true;
288        }
289
290        return false;
291    }
292
293    /**
294     * 画像のリサイズをおこなうかどうか
295     *
296     * @return bool
297     */
298    function isResizeImage($o_width = 0, $o_height = 0, $s_width = 0, $s_height = 0)
299    {
300        if (!$o_width && !$o_height) {
301            return false;
302        }
303
304        if (!$s_width || !$s_height) {
305            return true;
306        }
307
308        if ($s_width <= $o_width && $s_height <= $o_height) {
309            return false;
310        }
311
312        return true;
313    }
314
315    /**
316     * リサイズ後の画像サイズを算出する
317     */
318    function calcResizedImageSize(&$o_width, &$o_height, $s_width, $s_height)
319    {
320        $h = $s_height;
321        if ($o_width < $s_width) {
322            $h = $s_height * $o_width / $s_width;
323        }
324        if ($o_height < $h && $o_height < $s_height) {
325            $o_width = $s_width * $o_height / $s_height;
326        }
327
328        if ($o_height < 1.) {
329            $o_height = 1;
330        }
331        if ($o_width < 1.) {
332            $o_width = 1;
333        }
334    }
335
336    /**
337     * 入力画像から取得した透過情報を出力画像に適用する
338     */
339    function setTransparentToOutputImage(&$output_gdimg, &$source_gdimg)
340    {
341        if ($this->getOutputFormat() != 'gif' && $this->getOutputFormat() != 'png') {
342            return null;
343        }
344
345        $trnprt_idx_s = imagecolortransparent($source_gdimg);
346        if ($trnprt_idx_s >= 0) { // 透過色が設定されている
347            imagetruecolortopalette($output_gdimg, true, 256);
348
349            // 入力画像から透明色取得
350            $trnprt_color = imagecolorsforindex($source_gdimg, $trnprt_idx_s);
351
352            // 出力画像に透明色設定
353            imagecolorset($source_gdimg, 0, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
354            imagefill($output_gdimg, 0, 0, 0);
355            imagecolortransparent($output_gdimg, 0);
356        } elseif ($this->getOutputFormat() == 'png') {  // PNG-24
357            // アルファチャンネル情報を保存するには、アルファブレンディングを解除する必要がある
358            imagealphablending($output_gdimg, false);
359            imagesavealpha($output_gdimg, true);
360
361            // 透過色設定
362            $color = imagecolorallocatealpha($output_gdimg, 0, 0, 0, 127);
363            imagefill($output_gdimg, 0, 0, $color);
364        }
365    }
366}
367
368?>
Note: See TracBrowser for help on using the repository browser.