1 <?php
  2 
  3 /**
  4  * @package redaxo\media-manager
  5  */
  6 class rex_effect_mirror extends rex_effect_abstract
  7 {
  8     private $script;
  9 
 10     public function __construct()
 11     {
 12         $this->script = '
 13 <script type="text/javascript">
 14 <!--
 15 
 16 (function($) {
 17     $(function() {
 18         var $fx_mirror_select_trans = $("#media_manager_rex_effect_mirror_set_transparent_select");
 19         var $fx_mirror_bg_r = $("#media_manager_rex_effect_mirror_bg_r_text").parent().parent();
 20         var $fx_mirror_bg_g = $("#media_manager_rex_effect_mirror_bg_g_text").parent().parent();
 21         var $fx_mirror_bg_b = $("#media_manager_rex_effect_mirror_bg_b_text").parent().parent();
 22 
 23         $fx_mirror_select_trans.change(function(){
 24             if(jQuery(this).val() != "colored")
 25             {
 26                 $fx_mirror_bg_r.hide();
 27                 $fx_mirror_bg_g.hide();
 28                 $fx_mirror_bg_b.hide();
 29             }else
 30             {
 31                 $fx_mirror_bg_r.show();
 32                 $fx_mirror_bg_g.show();
 33                 $fx_mirror_bg_b.show();
 34             }
 35         }).change();
 36     });
 37 })(jQuery);
 38 
 39 //--></script>';
 40     }
 41 
 42     public function execute()
 43     {
 44         $this->media->asImage();
 45         $gdimage = $this->media->getImage();
 46 
 47         $w = $this->media->getWidth();
 48         $h = $this->media->getHeight();
 49 
 50         if (substr(trim($this->params['height']), -1) === '%') {
 51             $this->params['height'] = round($h * (rtrim($this->params['height'], '%') / 100));
 52         } else {
 53             $this->params['height'] = (int) $this->params['height'];
 54         }
 55         if ($this->params['height'] < 1) {
 56             $this->params['height'] = round($h / 2);
 57         }
 58 
 59         $this->params['bg_r'] = (int) $this->params['bg_r'];
 60         if (!isset($this->params['bg_r']) || $this->params['bg_r'] > 255 || $this->params['bg_r'] < 0) {
 61             $this->params['bg_r'] = 255;
 62         }
 63 
 64         $this->params['bg_g'] = (int) $this->params['bg_g'];
 65         if (!isset($this->params['bg_g']) || $this->params['bg_g'] > 255 || $this->params['bg_g'] < 0) {
 66             $this->params['bg_g'] = 255;
 67         }
 68 
 69         $this->params['bg_b'] = (int) $this->params['bg_b'];
 70         if (!isset($this->params['bg_b']) || $this->params['bg_b'] > 255 || $this->params['bg_b'] < 0) {
 71             $this->params['bg_b'] = 255;
 72         }
 73 
 74         if ($this->params['set_transparent'] != 'colored') {
 75             if ($this->media->getFormat() == 'webp') {
 76                 $this->media->setFormat('webp');
 77             } else {
 78                 $this->media->setFormat('png');
 79             }
 80         }
 81 
 82         $trans = false;
 83         if ($this->media->getFormat() == 'png' || $this->media->getFormat() == 'webp') {
 84             $trans = true;
 85         }
 86 
 87         $gdimage = $this->imagereflection($gdimage, $this->params['height'], $trans, [$this->params['bg_r'], $this->params['bg_g'], $this->params['bg_b']]);
 88         $this->media->setImage($gdimage);
 89         $this->media->refreshImageDimensions();
 90     }
 91 
 92     public function getName()
 93     {
 94         return rex_i18n::msg('media_manager_effect_mirror');
 95     }
 96 
 97     public function getParams()
 98     {
 99         return [
100             [
101                 'label' => rex_i18n::msg('media_manager_effect_mirror_height'),    // Length in Pixel or Prozent
102                 'name' => 'height',
103                 'type' => 'int',
104             ],
105             [
106                 'label' => rex_i18n::msg('media_manager_effect_mirror_background_color'),
107                 'name' => 'set_transparent',
108                 'type' => 'select',
109                 'options' => ['colored', 'transparent / png24'],
110                 'default' => 'colored',
111                 'suffix' => $this->script,
112             ],
113 
114             [
115                 'label' => rex_i18n::msg('media_manager_effect_mirror_background_r'),
116                 'name' => 'bg_r',
117                 'type' => 'int',
118             ],
119             [
120                 'label' => rex_i18n::msg('media_manager_effect_mirror_background_g'),
121                 'name' => 'bg_g',
122                 'type' => 'int',
123             ],
124             [
125                 'label' => rex_i18n::msg('media_manager_effect_mirror_background_b'),
126                 'name' => 'bg_b',
127                 'type' => 'int',
128             ],
129         ];
130     }
131 
132     private function imagereflection(&$src_img, $reflection_height, $trans, $bgcolor)
133     {
134         $src_height = imagesy($src_img);
135         $src_width = imagesx($src_img);
136         $dest_height = $src_height + $reflection_height;
137         $dest_width = $src_width;
138 
139         $reflected = imagecreatetruecolor($dest_width, $dest_height);
140         if ($trans) {
141             imagealphablending($reflected, false);
142             imagesavealpha($reflected, true);
143         } else {
144             // und mit Hintergrundfarbe füllen
145             imagefill($reflected, 0, 0, imagecolorallocate($reflected, $bgcolor[0], $bgcolor[1], $bgcolor[2]));
146         }
147 
148         imagecopy($reflected, $src_img, 0, 0, 0, 0, $src_width, $src_height);
149         $alpha_step = 80 / $reflection_height;
150         for ($y = 1; $y <= $reflection_height; ++$y) {
151             for ($x = 0; $x < $dest_width; ++$x) {
152                 $rgba = imagecolorat($src_img, $x, $src_height - $y);
153                 $alpha = ($rgba & 0x7F000000) >> 24;
154                 $alpha = max($alpha, 47 + ($y * $alpha_step));
155                 $rgba = imagecolorsforindex($src_img, $rgba);
156                 $rgba = imagecolorallocatealpha($reflected, $rgba['red'], $rgba['green'], $rgba['blue'], $alpha);
157                 imagesetpixel($reflected, $x, $src_height + $y - 1, $rgba);
158             }
159         }
160 
161         return $reflected;
162     }
163 }
164