source: trunk/include/derivative_params.inc.php @ 14221

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

feature 2606: second step on multiple size configuration screen redesign.

Configuration settings are saved on form submission.

The old screen is still available for tests.

Default resize quality set to 95 instead of 85.

File size: 7.3 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
22function derivative_to_url($t)
23{
24  return substr($t, 0, 2);
25}
26
27function size_to_url($s)
28{
29  if ($s[0]==$s[1])
30  {
31    return $s[0];
32  }
33  return $s[0].'x'.$s[1];
34}
35
36function size_equals($s1, $s2)
37{
38  return ($s1[0]==$s2[0] && $s1[1]==$s2[1]);
39}
40
41function char_to_fraction($c)
42{
43        return (ord($c) - ord('a'))/25;
44}
45
46function fraction_to_char($f)
47{
48        return chr(ord('a') + round($f*25));
49}
50
51/** small utility to manipulate a 'rectangle'*/
52final class ImageRect
53{
54  public $l,$t,$r,$b;
55
56  function __construct($l)
57  {
58    $this->l = $this->t = 0;
59    $this->r = $l[0];
60    $this->b = $l[1];
61  }
62
63  function width()
64  {
65    return $this->r - $this->l;
66  }
67
68  function height()
69  {
70    return $this->b - $this->t;
71  }
72
73  function crop_h($pixels, $coi)
74  {
75    if ($this->width() <= $pixels)
76      return;
77    $tlcrop = floor($pixels/2);
78
79    if (!empty($coi))
80    {
81      $coil = floor($this->r * char_to_fraction($coi[0]));
82      $coir = ceil($this->r * char_to_fraction($coi[2]));
83      $availableL = $coil > $this->l ? $coil - $this->l : 0;
84      $availableR = $coir < $this->r ? $this->r - $coir : 0;
85      if ($availableL + $availableR >= $pixels)
86      {
87        if ($availableL < $tlcrop)
88        {
89          $tlcrop = $availableL;
90        }
91        elseif ($availableR < $tlcrop)
92        {
93          $tlcrop = $pixels - $availableR;
94        }
95      }
96    }
97    $this->l += $tlcrop;
98    $this->r -= $pixels - $tlcrop;
99  }
100
101  function crop_v($pixels, $coi)
102  {
103    if ($this->height() <= $pixels)
104      return;
105    $tlcrop = floor($pixels/2);
106
107    if (!empty($coi))
108    {
109      $coit = floor($this->b * char_to_fraction($coi[1]));
110      $coib = ceil($this->b * char_to_fraction($coi[3]));
111      $availableT = $coit > $this->t ? $coit - $this->t : 0;
112      $availableB = $coib < $this->b ? $this->b - $coib : 0;
113      if ($availableT + $availableB >= $pixels)
114      {
115        if ($availableT < $tlcrop)
116        {
117          $tlcrop = $availableT;
118        }
119        elseif ($availableB < $tlcrop)
120        {
121          $tlcrop = $pixels - $availableB;
122        }
123      }
124    }
125    $this->t += $tlcrop;
126    $this->b -= $pixels - $tlcrop;
127  }
128
129}
130
131
132/*how we crop and/or resize an image*/
133final class SizingParams
134{
135  function __construct($ideal_size, $max_crop = 0, $min_size = null)
136  {
137    $this->ideal_size = $ideal_size;
138    $this->max_crop = $max_crop;
139    $this->min_size = $min_size;
140  }
141
142  static function classic($w, $h)
143  {
144    return new SizingParams( array($w,$h) );
145  }
146
147  static function square($w)
148  {
149    return new SizingParams( array($w,$w), 1, array($w,$w) );
150  }
151
152  function add_url_tokens(&$tokens)
153  {
154      if ($this->max_crop == 0)
155      {
156        $tokens[] = 's'.size_to_url($this->ideal_size);
157      }
158      elseif ($this->max_crop == 1 && size_equals($this->ideal_size, $this->min_size) )
159      {
160        $tokens[] = 'e'.size_to_url($this->ideal_size);
161      }
162      else
163      {
164        $tokens[] = size_to_url($this->ideal_size);
165        $tokens[] = fraction_to_char($this->max_crop);
166        $tokens[] = size_to_url($this->min_size);
167      }
168  }
169
170  function compute($in_size, $coi, &$crop_rect, &$scale_size)
171  {
172    $destCrop = new ImageRect($in_size);
173
174    if ($this->max_crop > 0)
175    {
176      $ratio_w = $destCrop->width() / $this->ideal_size[0];
177      $ratio_h = $destCrop->height() / $this->ideal_size[1];
178      if ($ratio_w>1 || $ratio_h>1)
179      {
180        if ($ratio_w > $ratio_h)
181        {
182          $h = $destCrop->height() / $ratio_w;
183          if ($h < $this->min_size[1])
184          {
185            $idealCropPx = $destCrop->width() - floor($destCrop->height() * $this->ideal_size[0] / $this->min_size[1]);
186            $maxCropPx = round($this->max_crop * $destCrop->width());
187            $destCrop->crop_h( min($idealCropPx, $maxCropPx), $coi);
188          }
189        }
190        else
191        {
192          $w = $destCrop->width() / $ratio_h;
193          if ($w < $this->min_size[0])
194          {
195            $idealCropPx = $destCrop->height() - floor($destCrop->width() * $this->ideal_size[1] / $this->min_size[0]);
196            $maxCropPx = round($this->max_crop * $destCrop->height());
197            $destCrop->crop_v( min($idealCropPx, $maxCropPx), $coi);
198          }
199        }
200      }
201    }
202
203    $scale_size = array($destCrop->width(), $destCrop->height());
204
205    $ratio_w = $destCrop->width() / $this->ideal_size[0];
206    $ratio_h = $destCrop->height() / $this->ideal_size[1];
207    if ($ratio_w>1 || $ratio_h>1)
208    {
209      if ($ratio_w > $ratio_h)
210      {
211        $scale_size[0] = $this->ideal_size[0];
212        $scale_size[1] = floor(1e-6 + $scale_size[1] / $ratio_w);
213      }
214      else
215      {
216        $scale_size[0] = floor(1e-6 + $scale_size[0] / $ratio_h);
217        $scale_size[1] = $this->ideal_size[1];
218      }
219    }
220    else
221    {
222      $scale_size = null;
223    }
224
225    $crop_rect = null;
226    if ($destCrop->width()!=$in_size[0] || $destCrop->height()!=$in_size[1] )
227    {
228      $crop_rect = $destCrop;
229    }
230  }
231
232}
233
234
235/*how we generate a derivative image*/
236final class DerivativeParams
237{
238  public $type = IMG_CUSTOM;
239  public $last_mod_time = 0; // used for non-custom images to regenerate the cached files
240  public $use_watermark = false;
241  public $sizing;
242  public $sharpen = 0;
243  public $quality = 95;
244
245  function __construct($sizing)
246  {
247    $this->sizing = $sizing;
248  }
249
250  public function __sleep()
251  {
252      return array('last_mod_time', 'sizing', 'sharpen', 'quality');
253  }
254
255  function add_url_tokens(&$tokens)
256  {
257    $this->sizing->add_url_tokens($tokens);
258  }
259
260  function compute_final_size($in_size)
261  {
262    $this->sizing->compute( $in_size, null, $crop_rect, $scale_size );
263    return $scale_size != null ? $scale_size : $in_size;
264  }
265
266  function max_width()
267  {
268    return $this->sizing->ideal_size[0];
269  }
270
271  function max_height()
272  {
273    return $this->sizing->ideal_size[1];
274  }
275
276  function is_identity($in_size)
277  {
278    if ($in_size[0] > $this->sizing->ideal_size[0] or
279        $in_size[1] > $this->sizing->ideal_size[1] )
280    {
281      return false;
282    }
283    return true;
284  }
285}
286?>
Note: See TracBrowser for help on using the repository browser.