1 <?php
  2 
  3 // Todo:
  4 // - Vergrößern erlauben oder nicht. aber eher als Modul einsetzen, also
  5 // fit
  6 
  7 /**
  8  * @package redaxo\media-manager
  9  */
 10 class rex_effect_resize extends rex_effect_abstract
 11 {
 12     private $options;
 13     private $script;
 14 
 15     public function __construct()
 16     {
 17         $this->options = ['maximum', 'minimum', 'exact'];
 18 
 19         $this->script = '
 20 <script type="text/javascript">
 21 <!--
 22 
 23 $(function() {
 24     var $fx_resize_select_style = $("#media-manager-rex-effect-resize-style-select");
 25     var $fx_resize_enlarge = $("#media-manager-rex-effect-resize-allow-enlarge-select").parent().parent();
 26 
 27     $fx_resize_select_style.change(function(){
 28         if(jQuery(this).val() == "exact")
 29         {
 30             $fx_resize_enlarge.hide();
 31         }else
 32         {
 33             $fx_resize_enlarge.show();
 34         }
 35     }).change();
 36 });
 37 
 38 //--></script>';
 39     }
 40 
 41     public function execute()
 42     {
 43         $this->media->asImage();
 44 
 45         $gdimage = $this->media->getImage();
 46         $w = $this->media->getWidth();
 47         $h = $this->media->getHeight();
 48 
 49         if (!isset($this->params['style']) || !in_array($this->params['style'], $this->options)) {
 50             $this->params['style'] = 'maximum';
 51         }
 52 
 53         // relatives resizen
 54         if (substr(trim($this->params['width']), -1) === '%') {
 55             $this->params['width'] = round($w * (rtrim($this->params['width'], '%') / 100));
 56         }
 57         if (substr(trim($this->params['height']), -1) === '%') {
 58             $this->params['height'] = round($h * (rtrim($this->params['height'], '%') / 100));
 59         }
 60 
 61         if ($this->params['style'] == 'maximum') {
 62             $this->resizeMax($w, $h);
 63         } elseif ($this->params['style'] == 'minimum') {
 64             $this->resizeMin($w, $h);
 65         }
 66         // warp => nichts tun
 67 
 68         // ----- not enlarge image
 69         if ($w <= $this->params['width'] && $h <= $this->params['height'] && $this->params['allow_enlarge'] == 'not_enlarge') {
 70             $this->params['width'] = $w;
 71             $this->params['height'] = $h;
 72             $this->keepTransparent($gdimage);
 73             return;
 74         }
 75 
 76         if (!isset($this->params['width'])) {
 77             $this->params['width'] = $w;
 78         }
 79 
 80         if (!isset($this->params['height'])) {
 81             $this->params['height'] = $h;
 82         }
 83 
 84         if (function_exists('ImageCreateTrueColor')) {
 85             $des = @imagecreatetruecolor($this->params['width'], $this->params['height']);
 86         } else {
 87             $des = @imagecreate($this->params['width'], $this->params['height']);
 88         }
 89 
 90         if (!$des) {
 91             return;
 92         }
 93 
 94         // Transparenz erhalten
 95         $this->keepTransparent($des);
 96         imagecopyresampled($des, $gdimage, 0, 0, 0, 0, $this->params['width'], $this->params['height'], $w, $h);
 97 
 98         $this->media->setImage($des);
 99         $this->media->refreshImageDimensions();
100     }
101 
102     private function resizeMax($w, $h)
103     {
104         if (!empty($this->params['height']) && !empty($this->params['width'])) {
105             $img_ratio = $w / $h;
106             $resize_ratio = $this->params['width'] / $this->params['height'];
107 
108             if ($img_ratio >= $resize_ratio) {
109                 // --- width
110                 $this->params['height'] = ceil($this->params['width'] / $w * $h);
111             } else {
112                 // --- height
113                 $this->params['width'] = ceil($this->params['height'] / $h * $w);
114             }
115         } elseif (!empty($this->params['height'])) {
116             $img_factor = $h / $this->params['height'];
117             $this->params['width'] = ceil($w / $img_factor);
118         } elseif (!empty($this->params['width'])) {
119             $img_factor = $w / $this->params['width'];
120             $this->params['height'] = ceil($h / $img_factor);
121         }
122     }
123 
124     private function resizeMin($w, $h)
125     {
126         if (!empty($this->params['height']) && !empty($this->params['width'])) {
127             $img_ratio = $w / $h;
128             $resize_ratio = $this->params['width'] / $this->params['height'];
129 
130             if ($img_ratio < $resize_ratio) {
131                 // --- width
132                 $this->params['height'] = ceil($this->params['width'] / $w * $h);
133             } else {
134                 // --- height
135                 $this->params['width'] = ceil($this->params['height'] / $h * $w);
136             }
137         } elseif (!empty($this->params['height'])) {
138             $img_factor = $h / $this->params['height'];
139             $this->params['width'] = ceil($w / $img_factor);
140         } elseif (!empty($this->params['width'])) {
141             $img_factor = $w / $this->params['width'];
142             $this->params['height'] = ceil($h / $img_factor);
143         }
144     }
145 
146     public function getName()
147     {
148         return rex_i18n::msg('media_manager_effect_resize');
149     }
150 
151     public function getParams()
152     {
153         return [
154             [
155                 'label' => rex_i18n::msg('media_manager_effect_resize_width'),
156                 'name' => 'width',
157                 'type' => 'int',
158             ],
159             [
160                 'label' => rex_i18n::msg('media_manager_effect_resize_height'),
161                 'name' => 'height',
162                 'type' => 'int',
163             ],
164             [
165                 'label' => rex_i18n::msg('media_manager_effect_resize_style'),
166                 'name' => 'style',
167                 'type' => 'select',
168                 'options' => $this->options,
169                 'default' => 'fit',
170                 'suffix' => $this->script,
171             ],
172             [
173                 'label' => rex_i18n::msg('media_manager_effect_resize_imgtosmall'),
174                 'name' => 'allow_enlarge',
175                 'type' => 'select',
176                 'options' => ['enlarge', 'not_enlarge'],
177                 'default' => 'enlarge',
178             ],
179         ];
180     }
181 }
182