source: trunk/include/derivative.inc.php @ 13843

Last change on this file since 13843 was 13843, checked in by plg, 12 years ago

feature 2604: support rotation on derivatives

File size: 7.8 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based photo gallery                                    |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2012 Piwigo Team                  http://piwigo.org |
6// +-----------------------------------------------------------------------+
7// | This program is free software; you can redistribute it and/or modify  |
8// | it under the terms of the GNU General Public License as published by  |
9// | the Free Software Foundation                                          |
10// |                                                                       |
11// | This program is distributed in the hope that it will be useful, but   |
12// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
13// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
14// | General Public License for more details.                              |
15// |                                                                       |
16// | You should have received a copy of the GNU General Public License     |
17// | along with this program; if not, write to the Free Software           |
18// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
19// | USA.                                                                  |
20// +-----------------------------------------------------------------------+
21
22final class SrcImage
23{
24  const IS_ORIGINAL = 0x01;
25  const IS_MIMETYPE = 0x02;
26
27  public $id;
28  public $rel_path;
29
30  private $size=null;
31  private $flags=0;
32
33  function __construct($infos)
34  {
35    global $conf;
36
37    $this->id = $infos['id'];
38    $ext = get_extension($infos['path']);
39    if (in_array($ext, $conf['picture_ext']))
40    {
41      $this->rel_path = $infos['path'];
42      $this->flags |= self::IS_ORIGINAL;
43    }
44    elseif (!empty($infos['representative_ext']))
45    {
46      $this->rel_path = original_to_representative($infos['path'], $infos['representative_ext']);
47    }
48    else
49    {
50      $ext = strtolower($ext);
51      $this->rel_path = trigger_event('get_mimetype_location', get_themeconf('mime_icon_dir').$ext.'.png', $ext );
52      $this->flags |= self::IS_MIMETYPE;
53      $this->size = @getimagesize(PHPWG_ROOT_PATH.$this->rel_path);
54    }
55
56    if (!$this->size && isset($infos['width']) && isset($infos['height']))
57    {
58      $width = $infos['width'];
59      $height = $infos['height'];
60
61      // 1 or 5 =>  90 clockwise
62      // 3 or 7 => 270 clockwise
63      if ($infos['rotation'] % 2 != 0)
64      {
65        $width = $infos['height'];
66        $height = $infos['width'];
67      }
68     
69      $this->size = array($width, $height);
70    }
71  }
72
73  function is_original()
74  {
75    return $this->flags & self::IS_ORIGINAL;
76  }
77
78  function is_mimetype()
79  {
80    return $this->flags & self::IS_MIMETYPE;
81  }
82
83  function get_path()
84  {
85    return PHPWG_ROOT_PATH.$this->rel_path;
86  }
87
88  function get_url()
89  {
90    $url = get_root_url().$this->rel_path;
91    if ($this->flags & self::IS_ORIGINAL)
92    {
93      $url = trigger_event('get_src_image_url', $url, $this);
94    }
95    return embellish_url($url);
96  }
97
98  function has_size()
99  {
100    return $this->size != null;
101  }
102
103  function get_size()
104  {
105    if ($this->size == null)
106      not_implemented(); // get size from file
107    return $this->size;
108  }
109}
110
111
112
113final class DerivativeImage
114{
115  public $src_image;
116
117  private $params;
118  private $rel_path, $rel_url, $is_cached=true;
119
120  function __construct($type, $src_image)
121  {
122    $this->src_image = $src_image;
123    if (is_string($type))
124    {
125      $this->params = ImageStdParams::get_by_type($type);
126    }
127    else
128    {
129      $this->params = $type;
130    }
131
132    self::build($src_image, $this->params, $this->rel_path, $this->rel_url, $this->is_cached);
133  }
134
135  static function thumb_url($infos)
136  {
137    return self::url(IMG_THUMB, $infos);
138  }
139
140  static function url($type, $infos)
141  {
142    $src_image = is_object($infos) ? $infos : new SrcImage($infos);
143    $params = is_string($type) ? ImageStdParams::get_by_type($type) : $type;
144    self::build($src_image, $params, $rel_path, $rel_url);
145    if ($params == null)
146    {
147      return $src_image->get_url();
148    }
149    return embellish_url(
150        trigger_event('get_derivative_url',
151          get_root_url().$rel_url,
152          $params, $src_image, $rel_url
153          ) );
154  }
155
156  static function get_all($src_image)
157  {
158    $ret = array();
159    foreach (ImageStdParams::get_defined_type_map() as $type => $params)
160    {
161      $derivative = new DerivativeImage($params, $src_image);
162      $ret[$type] = $derivative;
163    }
164    foreach (ImageStdParams::get_undefined_type_map() as $type => $type2)
165    {
166      $ret[$type] = $ret[$type2];
167    }
168
169    return $ret;
170  }
171
172  private static function build($src, &$params, &$rel_path, &$rel_url, &$is_cached=null)
173  {
174    if ( $src->has_size() && $params->is_identity( $src->get_size() ) )
175    {
176      // todo - what if we have a watermark maybe return a smaller size?
177      $params = null;
178      $rel_path = $rel_url = $src->rel_path;
179      return;
180    }
181
182    $tokens=array();
183    $tokens[] = substr($params->type,0,2);
184
185    if ($params->type==IMG_CUSTOM)
186    {
187      $params->add_url_tokens($tokens);
188    }
189
190    $loc = $src->rel_path;
191    if (substr_compare($loc, './', 0, 2)==0)
192    {
193      $loc = substr($loc, 2);
194    }
195    elseif (substr_compare($loc, '../', 0, 3)==0)
196    {
197      $loc = substr($loc, 3);
198    }
199    $loc = substr_replace($loc, '-'.implode('_', $tokens), strrpos($loc, '.'), 0 );
200
201    $rel_path = PWG_DERIVATIVE_DIR.$loc;
202
203    global $conf;
204    $url_style=$conf['derivative_url_style'];
205    if (!$url_style)
206    {
207      $mtime = @filemtime(PHPWG_ROOT_PATH.$rel_path);
208      if ($mtime===false or $mtime < $params->last_mod_time)
209      {
210        $is_cached = false;
211        $url_style = 2;
212      }
213      else
214      {
215        $url_style = 1;
216      }
217    }
218
219    if ($url_style == 2)
220    {
221      $rel_url = 'i';
222      if ($conf['php_extension_in_urls']) $rel_url .= '.php';
223      if ($conf['question_mark_in_urls']) $rel_url .= '?';
224      $rel_url .= '/'.$loc;
225    }
226    else
227    {
228      $rel_url = $rel_path;
229    }
230  }
231
232  function get_path()
233  {
234    return PHPWG_ROOT_PATH.$this->rel_path;
235  }
236
237  function get_url()
238  {
239    if ($this->params == null)
240    {
241      return $this->src_image->get_url();
242    }
243    return embellish_url(
244        trigger_event('get_derivative_url',
245          get_root_url().$this->rel_url,
246          $this->params, $this->src_image, $this->rel_url
247          ) );
248  }
249
250  function same_as_source()
251  {
252    return $this->params == null;
253  }
254
255
256  function get_type()
257  {
258    if ($this->params == null)
259      return 'Original';
260    return $this->params->type;
261  }
262
263  /* returns the size of the derivative image*/
264  function get_size()
265  {
266    if ($this->params == null)
267    {
268      return $this->src_image->get_size();
269    }
270    return $this->params->compute_final_size($this->src_image->get_size());
271  }
272
273  function get_size_htm()
274  {
275    $size = $this->get_size();
276    if ($size)
277    {
278      return 'width="'.$size[0].'" height="'.$size[1].'"';
279    }
280  }
281
282  function get_size_hr()
283  {
284    $size = $this->get_size();
285    if ($size)
286    {
287      return $size[0].' x '.$size[1];
288    }
289  }
290
291  function get_scaled_size($maxw, $maxh)
292  {
293    $size = $this->get_size();
294    if ($size)
295    {
296      $ratio_w = $size[0] / $maxw;
297      $ratio_h = $size[1] / $maxh;
298      if ($ratio_w>1 || $ratio_h>1)
299      {
300        if ($ratio_w > $ratio_h)
301        {
302          $size[0] = $maxw;
303          $size[1] = floor($size[1] / $ratio_w);
304        }
305        else
306        {
307          $size[0] = floor($size[0] / $ratio_h);
308          $size[1] = $maxh;
309        }
310      }
311    }
312    return $size;
313  }
314
315  function get_scaled_size_htm($maxw=9999, $maxh=9999)
316  {
317    $size = $this->get_scaled_size($maxw, $maxh);
318    if ($size)
319    {
320      return 'width="'.$size[0].'" height="'.$size[1].'"';
321    }
322  }
323
324  function is_cached()
325  {
326    return $this->is_cached;
327  }
328}
329
330?>
Note: See TracBrowser for help on using the repository browser.