freakstyle

~~~ Really only another WordPress ? ~~~

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->im1false);
        
imagesavealpha($this->im1true);
        
$width imagesx($this->im1);
        
$height imagesy($this->im1);
        
//
        //creo la nuova immagine
        
$this->im2 = @imagecreatetruecolor($widthintval($height*($perc))) or die(
            
"Cannot Initialize new GD image stream"
        
);
        
imagealphablending($this->im2false);
        
imagesavealpha($this->im2true);
        
//
        //copio la parte originale dell'immagine
        
imagecopy($this->im2$this->im10000$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->im2000127 )
                );    
            }
        }
        if(
$this->im2!==NULL){
            
header("Content-Type: image/".$func_ext);
            
$img_close($this->im2);
        }
        return 
$this;
    }
    
//
    
private function getRGB($im$x$y){
        return 
imagecolorsforindex($imimagecolorat($im$x$y) );
    }
    private function 
file_ext($filename){
        
$tmp explode('.',$filename);
        return 
array_pop($tmp);
    }
}
//
//
//
$filename $_GET['im'];
$eff = new image_eff();
$eff -> refl($filename0.21, -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'4503370.50.80.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

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Categorised as: php


Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>