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

Last change on this file since 18887 was 16989, checked in by rvelices, 12 years ago

bug 2682: Watermark sizing calculation is made on the requested size not on the final one

File size: 9.4 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  const DIM_NOT_GIVEN = 0x04;
27
28  public $id;
29  public $rel_path;
30  public $rotation = 0;
31
32  private $size=null;
33  private $flags=0;
34
35  function __construct($infos)
36  {
37    global $conf;
38
39    $this->id = $infos['id'];
40    $ext = get_extension($infos['path']);
41    if (in_array($ext, $conf['picture_ext']))
42    {
43      $this->rel_path = $infos['path'];
44      $this->flags |= self::IS_ORIGINAL;
45    }
46    elseif (!empty($infos['representative_ext']))
47    {
48      $this->rel_path = original_to_representative($infos['path'], $infos['representative_ext']);
49    }
50    else
51    {
52      $ext = strtolower($ext);
53      $this->rel_path = trigger_event('get_mimetype_location', get_themeconf('mime_icon_dir').$ext.'.png', $ext );
54      $this->flags |= self::IS_MIMETYPE;
55      if ( ($size=@getimagesize(PHPWG_ROOT_PATH.$this->rel_path)) === false)
56      {
57        $this->rel_path = 'themes/default/icon/mimetypes/unknown.png';
58        $size = getimagesize(PHPWG_ROOT_PATH.$this->rel_path);
59      }
60      $this->size = array($size[0],$size[1]);
61    }
62
63    if (!$this->size)
64    {
65      if (isset($infos['width']) && isset($infos['height']))
66      {
67        $width = $infos['width'];
68        $height = $infos['height'];
69
70        $this->rotation = intval($infos['rotation']) % 4;
71        // 1 or 5 =>  90 clockwise
72        // 3 or 7 => 270 clockwise
73        if ($this->rotation % 2)
74        {
75          $width = $infos['height'];
76          $height = $infos['width'];
77        }
78       
79        $this->size = array($width, $height);
80      }
81      elseif (!array_key_exists('width', $infos))
82      {
83        $this->flags |= self::DIM_NOT_GIVEN;
84      }
85    }
86  }
87
88  function is_original()
89  {
90    return $this->flags & self::IS_ORIGINAL;
91  }
92
93  function is_mimetype()
94  {
95    return $this->flags & self::IS_MIMETYPE;
96  }
97
98  function get_path()
99  {
100    return PHPWG_ROOT_PATH.$this->rel_path;
101  }
102
103  function get_url()
104  {
105    $url = get_root_url().$this->rel_path;
106    if ($this->flags & self::IS_ORIGINAL)
107    {
108      $url = trigger_event('get_src_image_url', $url, $this);
109    }
110    return embellish_url($url);
111  }
112
113  function has_size()
114  {
115    return $this->size != null;
116  }
117
118  function get_size()
119  {
120    if ($this->size == null)
121    {
122      if ($this->flags & self::DIM_NOT_GIVEN)
123        fatal_error('SrcImage dimensions required but not provided');
124      // probably not metadata synced
125      if ( ($size = getimagesize( $this->get_path() )) !== false)
126      {
127        $this->size = array($size[0],$size[1]);
128        pwg_query('UPDATE '.IMAGES_TABLE.' SET width='.$size[0].', height='.$size[1].' WHERE id='.$this->id);
129      }
130    }
131    return $this->size;
132  }
133}
134
135
136
137final class DerivativeImage
138{
139  public $src_image;
140
141  private $params;
142  private $rel_path, $rel_url, $is_cached=true;
143
144  function __construct($type, $src_image)
145  {
146    $this->src_image = $src_image;
147    if (is_string($type))
148    {
149      $this->params = ImageStdParams::get_by_type($type);
150    }
151    else
152    {
153      $this->params = $type;
154    }
155
156    self::build($src_image, $this->params, $this->rel_path, $this->rel_url, $this->is_cached);
157  }
158
159  static function thumb_url($infos)
160  {
161    return self::url(IMG_THUMB, $infos);
162  }
163
164  static function url($type, $infos)
165  {
166    $src_image = is_object($infos) ? $infos : new SrcImage($infos);
167    $params = is_string($type) ? ImageStdParams::get_by_type($type) : $type;
168    self::build($src_image, $params, $rel_path, $rel_url);
169    if ($params == null)
170    {
171      return $src_image->get_url();
172    }
173    return embellish_url(
174        trigger_event('get_derivative_url',
175          get_root_url().$rel_url,
176          $params, $src_image, $rel_url
177          ) );
178  }
179
180  static function get_all($src_image)
181  {
182    $ret = array();
183    foreach (ImageStdParams::get_defined_type_map() as $type => $params)
184    {
185      $derivative = new DerivativeImage($params, $src_image);
186      $ret[$type] = $derivative;
187    }
188    foreach (ImageStdParams::get_undefined_type_map() as $type => $type2)
189    {
190      $ret[$type] = $ret[$type2];
191    }
192
193    return $ret;
194  }
195
196  private static function build($src, &$params, &$rel_path, &$rel_url, &$is_cached=null)
197  {
198    if ( $src->has_size() && $params->is_identity( $src->get_size() ) )
199    {
200      if (!$params->will_watermark($src->get_size()) && !$src->rotation)
201      {
202        $params = null;
203        $rel_path = $rel_url = $src->rel_path;
204        return;
205      }
206      $defined_types = array_keys(ImageStdParams::get_defined_type_map());
207      for ($i=0; $i<count($defined_types); $i++)
208      {
209        if ($defined_types[$i] == $params->type)
210        {
211          for ($i--; $i>=0; $i--)
212          {
213            $smaller = ImageStdParams::get_by_type($defined_types[$i]);
214            if ($smaller->sizing->max_crop==$params->sizing->max_crop && $smaller->is_identity( $src->get_size() ))
215            {
216              $params = $smaller;
217              self::build($src, $params, $rel_path, $rel_url, $is_cached);
218              return;
219            }
220          }
221          break;
222        }
223      }
224    }
225
226    $tokens=array();
227    $tokens[] = substr($params->type,0,2);
228
229    if ($params->type==IMG_CUSTOM)
230    {
231      $params->add_url_tokens($tokens);
232    }
233
234    $loc = $src->rel_path;
235    if (substr_compare($loc, './', 0, 2)==0)
236    {
237      $loc = substr($loc, 2);
238    }
239    elseif (substr_compare($loc, '../', 0, 3)==0)
240    {
241      $loc = substr($loc, 3);
242    }
243    $loc = substr_replace($loc, '-'.implode('_', $tokens), strrpos($loc, '.'), 0 );
244
245    $rel_path = PWG_DERIVATIVE_DIR.$loc;
246
247    global $conf;
248    $url_style=$conf['derivative_url_style'];
249    if (!$url_style)
250    {
251      $mtime = @filemtime(PHPWG_ROOT_PATH.$rel_path);
252      if ($mtime===false or $mtime < $params->last_mod_time)
253      {
254        $is_cached = false;
255        $url_style = 2;
256      }
257      else
258      {
259        $url_style = 1;
260      }
261    }
262
263    if ($url_style == 2)
264    {
265      $rel_url = 'i';
266      if ($conf['php_extension_in_urls']) $rel_url .= '.php';
267      if ($conf['question_mark_in_urls']) $rel_url .= '?';
268      $rel_url .= '/'.$loc;
269    }
270    else
271    {
272      $rel_url = $rel_path;
273    }
274  }
275
276  function get_path()
277  {
278    return PHPWG_ROOT_PATH.$this->rel_path;
279  }
280
281  function get_url()
282  {
283    if ($this->params == null)
284    {
285      return $this->src_image->get_url();
286    }
287    return embellish_url(
288        trigger_event('get_derivative_url',
289          get_root_url().$this->rel_url,
290          $this->params, $this->src_image, $this->rel_url
291          ) );
292  }
293
294  function same_as_source()
295  {
296    return $this->params == null;
297  }
298
299
300  function get_type()
301  {
302    if ($this->params == null)
303      return 'Original';
304    return $this->params->type;
305  }
306
307  /* returns the size of the derivative image*/
308  function get_size()
309  {
310    if ($this->params == null)
311    {
312      return $this->src_image->get_size();
313    }
314    return $this->params->compute_final_size($this->src_image->get_size());
315  }
316
317  function get_size_css()
318  {
319    $size = $this->get_size();
320    if ($size)
321    {
322      return 'width:'.$size[0].'px; height:'.$size[1].'px';
323    }
324  }
325
326  function get_size_htm()
327  {
328    $size = $this->get_size();
329    if ($size)
330    {
331      return 'width="'.$size[0].'" height="'.$size[1].'"';
332    }
333  }
334
335  function get_size_hr()
336  {
337    $size = $this->get_size();
338    if ($size)
339    {
340      return $size[0].' x '.$size[1];
341    }
342  }
343
344  function get_scaled_size($maxw, $maxh)
345  {
346    $size = $this->get_size();
347    if ($size)
348    {
349      $ratio_w = $size[0] / $maxw;
350      $ratio_h = $size[1] / $maxh;
351      if ($ratio_w>1 || $ratio_h>1)
352      {
353        if ($ratio_w > $ratio_h)
354        {
355          $size[0] = $maxw;
356          $size[1] = floor($size[1] / $ratio_w);
357        }
358        else
359        {
360          $size[0] = floor($size[0] / $ratio_h);
361          $size[1] = $maxh;
362        }
363      }
364    }
365    return $size;
366  }
367
368  function get_scaled_size_htm($maxw=9999, $maxh=9999)
369  {
370    $size = $this->get_scaled_size($maxw, $maxh);
371    if ($size)
372    {
373      return 'width="'.$size[0].'" height="'.$size[1].'"';
374    }
375  }
376
377  function is_cached()
378  {
379    return $this->is_cached;
380  }
381}
382
383?>
Note: See TracBrowser for help on using the repository browser.