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

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

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

幅と高さが引数によって与えられていた画像生成関数を、メンバ変数を参照するように変更

File size: 8.9 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;
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, $format)
52    {
53        if (!$this->isAllowedSize($this->width, $this->height)) {
54            return false;
55        }
56
57        // サイズ指定がなく、かつ、形式変換しない場合(GDに変換する必要なし)
58        if (!$this->width && !$this->height && ($this->getSourceFormat() == $this->getOutputFormat())) {
59            $this->createCacheFromRawImage($this->cache_fullpath, $this->cache_dir, $raw_img);
60            return true;
61        }
62
63        // create a GD image from raw_img
64        if (!$source_gdimg  = imagecreatefromstring($raw_img)) {
65            return false;
66        }
67
68        if ($format == 'jpg') {
69            // JPEGの場合、携帯対応
70            imageinterlace($source_gdimg, 0);
71        }
72
73        // リサイズ
74        $output_img = $this->resizeImage($source_gdimg);
75
76        // キャッシュを生成
77        if ($output_img) {
78            $this->createCache($this->cache_fullpath, $this->cache_dir, $output_img);
79        } else {
80            $this->createCacheFromRawImage($this->cache_fullpath, $this->cache_dir, $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        // リサイズの必要がない場合
107        if ($s_width <= $o_width && $s_height <= $o_height) {
108            // 形式変換する場合はGDを通す
109            if ($this->source_format != $this->output_format) {
110                return $source_gdimg;
111            }
112            return false;
113        }
114
115        if ($o_width < $s_width) {
116            $o_height = $s_height * $o_width / $s_width;
117        }
118        if ($o_height < $o_height && $o_height < $s_height) {
119            $o_width  = $s_width * $o_height / $s_height;
120        }
121
122        if ($o_height < 1.) {
123            $o_height = 1;
124        }
125        if ($o_width < 1.) {
126            $o_width = 1;
127        }
128
129        $output_gdimg = imagecreatetruecolor($o_width, $o_height);
130
131        if (($this->output_format == 'gif') || ($this->output_format == 'png')) {
132            $trnprt_idx_s = imagecolortransparent($source_gdimg);
133            if ($trnprt_idx_s >= 0) { // 透過色が設定されている
134                imagetruecolortopalette($output_gdimg, true, 256);
135
136                // 入力画像から透明色取得
137                $trnprt_color = imagecolorsforindex($source_gdimg, $trnprt_idx_s);
138
139                // 出力画像に透明色設定
140                imagecolorset($source_gdimg, 0, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
141                imagefill($output_gdimg, 0, 0, 0);
142                imagecolortransparent($output_gdimg, 0);
143            } elseif ($this->output_format == 'png') {  // PNG-24
144                // アルファチャンネル情報を保存するには、アルファブレンディングを解除する必要がある
145                imagealphablending($output_gdimg, false);
146                imagesavealpha($output_gdimg, true);
147
148                // 透過色設定
149                $color = imagecolorallocatealpha($output_gdimg, 0, 0, 0, 127);
150                imagefill($output_gdimg, 0, 0, $color);
151            }
152        }
153
154        imagecopyresampled($output_gdimg, $source_gdimg,
155                0, 0, 0, 0, $o_width, $o_height, $s_width, $s_height);
156        return $output_gdimg;
157    }
158
159    function createCacheFromRawImage($cache_fullpath, $cache_dir, $raw_img)
160    {
161        $this->createCacheSubdir($cache_fullpath, $cache_dir);
162
163        if ($this->getOutputFormat() == 'png') {
164            touch($cache_fullpath);
165            $output_gdimg = imagecreatefromstring($raw_img);
166            imagepng($output_gdimg, $cache_fullpath);
167        } else {
168            $handle = fopen($cache_fullpath, 'wb');
169            fwrite($handle, $raw_img);
170            fclose($handle);
171        }
172    }
173
174    function createCache($cache_fullpath, $cache_dir, $output_gdimg)
175    {
176        $this->createCacheSubdir($cache_fullpath, $cache_dir);
177
178        touch($cache_fullpath);
179        switch ($this->getOutputFormat()) {
180        case 'jpeg':
181        case 'jpg':
182        default:
183            imagejpeg($output_gdimg, $cache_fullpath, $this->jpeg_quality); break;
184        case 'gif':
185            imagegif($output_gdimg, $cache_fullpath);
186            break;
187        case 'png':
188            imagepng($output_gdimg, $cache_fullpath);
189            break;
190        }
191    }
192
193    function createCacheSubdir($cache_fullpath, $cache_dir)
194    {
195        $subdir = dirname($cache_fullpath);
196        if (!is_dir($subdir)) {
197            // mkdir recursive
198            $_dir = $cache_dir;
199            if (!is_dir($_dir) && !mkdir($_dir)) {
200                return false;
201            }
202            $relative_path = substr($subdir, strlen($cache_dir)+1);
203            $parts = explode('/', $relative_path);
204            foreach ($parts as $part) {
205                $_dir .=  '/' . $part;
206                if (!is_dir($_dir) && !mkdir($_dir)) {
207                    return false;
208                }
209            }
210        }
211    }
212
213    function checkFormatString($string)
214    {
215        $string = strtolower($string);
216
217        $format = 'jpg';
218        if ($string == 'gif' || $string == 'png') {
219            $format = $string;
220        }
221       
222        return $format;
223    }
224
225    function setCacheFileName($filename)
226    {
227        $pieces = explode('.', $filename);
228        $this->setSourceFormat($this->checkFormatString(array_pop($pieces)));
229
230        $f = $this->getOutputFormat();
231
232        $this->cache_fullpath =
233                 $this->cache_dir . '/' .
234                 $this->getCachePath($filename, $this->width, $this->height, $f);
235    }
236
237    function setOutputFormat($output_format = '')
238    {
239        if ($output_format) {
240            $this->output_format = $this->checkFormatString($output_format);
241        } else {
242            $this->output_format = $this->checkFormatString($this->getSourceFormat());
243        }
244    }
245
246    /**
247     * ファイルの高さ・幅をセット
248     *
249     * @param int $width
250     * @param int $height
251     */
252    function setImageSize($width = 0, $height = 0)
253    {
254        if (is_numeric($width)) {
255            $this->width = $width;
256        }
257
258        if (is_numeric($height)) {
259            $this->height = $height;
260        }
261    }
262
263    function setSourceFormat($source_format)
264    {
265        $this->source_format = $source_format;
266    }
267
268    function getOutputFormat()
269    {
270        return $this->output_format;
271    }
272
273    function getSourceFormat()
274    {
275        return $this->source_format;
276    }
277
278    function getCacheFullpath()
279    {
280        return $this->cache_fullpath;
281    }
282
283    function getCachePath($filename, $w, $h, $f)
284    {
285        $prefix = OPENPNE_IMG_CACHE_PREFIX;
286
287        if (!$w) $w = '';
288        if (!$h) $h = '';
289        $file = str_replace('.', '_', $filename) . '.' . $f;
290
291        $path = "{$f}/w{$w}_h{$h}/{$prefix}{$file}";
292        return $path;
293    }
294
295    function isCacheReadable()
296    {
297        return is_readable($this->cache_fullpath);
298    }
299
300    /**
301     * 変換可能な画像サイズかどうか
302     *
303     * @param int $width
304     * @param int $height
305     * @return bool
306     */
307    function isAllowedSize($width = 0, $height = 0)
308    {
309        if (!$width && !$height) {
310            return true;
311        }
312
313        $size = sprintf('%dx%d', $width, $height);
314        if ($this->allowed_size && !in_array($size, $this->allowed_size)) {
315            return false;
316        }
317
318        return true;
319    }
320}
321
322?>
Note: See TracBrowser for help on using the repository browser.