Effetto riflesso alle immagini con php gd

Vediamo come creare, tramite le gd2 di php, delle immagini con l’effetto a specchio nella parte bassa dell’immagine, e alla fine vedremo come ottenere un effetto molto simile senza le gd, con un ottimo risultato.
<?php
class image_eff{
private $im1, $im2;
public function __construct(){
$this->im1=NULL;
$this->im2=NULL;
}
public function refl($imgname, $perc, $inperc, $correction = 0){
//$correction: coefficiente di modifica componenti riflesse[-100, 100]
//cosi posso specificare inperc come percentuale
$inperc = (1/$perc)*$inperc;
//preparo la prima immagine
$ext = $this->file_ext($imgname);
$func_ext = (in_array($ext, array('jpg','jpeg') ))?'jpeg':$ext;
$img_open = 'imagecreatefrom'.$func_ext;
$img_close = 'image'.((in_array($ext, array('jpg','jpeg') ))?'jpeg':$ext);
//
$this->im1 = @$img_open($imgname);
imagealphablending($this->im1, false);
imagesavealpha($this->im1, true);
$width = imagesx($this->im1);
$height = imagesy($this->im1);
//
//creo la nuova immagine
$this->im2 = @imagecreatetruecolor($width, intval($height*(1 + $perc))) or die(
"Cannot Initialize new GD image stream"
);
imagealphablending($this->im2, false);
imagesavealpha($this->im2, true);
//
//copio la parte originale dell'immagine
imagecopy($this->im2, $this->im1, 0, 0, 0, 0, $width, $height);
//
// PER ORA non so davvero perche' , ma con 64 funziona
$thresold = 2<<5; // e' una soglia per decidere che fare in caso ci siano alpha (png)
//
for($y=0; $y < intval( $height * $perc ); $y++){
//[0,127]
$p =intval( $y*127/ ($height * $perc));
for($x=0; $x<$width; $x++){
$colRGB = $this->getRGB($this->im1, $x, $height-$y*$inperc-1);
//
$steps = array(
'red' => min(array(255 - $colRGB['red'] ,$colRGB['red'] )) / 100,
'green' => min(array(255 - $colRGB['green'] , $colRGB['green'] )) / 100,
'blue' => min(array(255 - $colRGB['blue'] , $colRGB['blue'] )) / 100,
);
foreach($colRGB as $k=>$c) $colRGB[$k] += intval($steps[$k]*$correction);
//
imagesetpixel(
$this->im2,
$x,
$height+$y,
($colRGB['alpha'] < $thresold) ?
imagecolorexactalpha (
$this->im2,
abs($colRGB['red']),
abs($colRGB['green']),
abs($colRGB['blue']),
$p
)
:
imagecolorallocatealpha($this->im2, 0, 0, 0, 127 )
);
}
}
if($this->im2!==NULL){
header("Content-Type: image/".$func_ext);
$img_close($this->im2);
}
return $this;
}
//
private function getRGB($im, $x, $y){
return imagecolorsforindex($im, imagecolorat($im, $x, $y) );
}
private function file_ext($filename){
$tmp = explode('.',$filename);
return array_pop($tmp);
}
}
//
//
//
$filename = $_GET['im'];
$eff = new image_eff();
$eff -> refl($filename, 0.2, 1, -70);
qui i parametri non banali di refl() sono:
$perc : percentuale dell’immagine originale (da 0 a 1) dello spazio che verra’ aggiunto per il riflesso;
$inperc: percentuale dell’immagine originale (da 0 a 1) che verra’mostrato nell`area di riflessione;
$correction: valore che di default vale 0 (non influendo), mentre se diverso da 0 schiarisce o scurisce il riflesso a seconda che sia maggiore o minore di zero; agli estremi si ottiene il massimo effetto possibile senza alterare le differenze cromatiche tra i vari pixel.
Ora, supponendo di aver chiamato il file sopra “image.php”, basta puntare a questo file nell’attributo src di un’immagine, passando in get il parametro im con la path all’immagine (relativa al file image.php)
<img src="image.php?im=prova.jpg" />
ottenendo quanto visto all’inizio del post.
Funziona con jpeg, gif e nel caso delle png viene preservata la trasparenza e la parte riflessa viene sfumata.
E se non abbiamo le gd?
Se siamo disposti a prenderci un po di divite allora possiamo usare la seguente funzione:
<?php
function noGD_refl($imgname, $w, $h, $perc=1, $inperc=1, $g=1){
$out = '';
echo '<div id="ext">';
echo '<img src="'.$imgname.'" style="border:0px; padding:0px; margin:0px" />';
for($i = $h-1, $j = 0; $i > $h*(1-$perc); $i--, $j++){
$tmp = $h-$i;
$opacity = ($g)? $g-($tmp/($h*(1-$perc))) : 1;
// retta per due punti [$h*(1-$perc)-1, 0] e [$h-1, $h-1]
// tenendo anche conto di un fattore di scala $inperc
$minus = ($h-1)*(1-$inperc) +
$inperc*(($h-1)/($h-1-($h*(1-$perc)-1) ))*($i-($h*(1-$perc)-1)) -0;
$x = "<div style=\"width:".
$w.
"px;height:1px;background:url(".
$imgname.
") 0px -".
$minus.
"px;repeat:norepeat;opacity:".
$opacity.
";filter: alpha(opacity = ".
ceil(($opacity*100)).
");\"></div>";
$out = $out.$x;
}
echo $out;
echo '</div>';
}
//
noGD_refl('prova.jpg', 450, 337, 0.5, 0.8, 0.7);
qui si hanno vantaggi e svantaggi, il vantaggio e’ che l’effetto alpha funziona con tutte le immagini, non solo con png, visto che e’ dato da css; lo svantaggio e’ che si creano ben h div.
I parametri sono nome, larghezza, altezza, percentuale di spazio per la riflessione (rispetto h), percentuale di immagine riflessa nello spazio a disposizione, fattore per regolare alpha.
Il risultato e’ il seguente:
Ciao
Federico
Categorised as: php












