2012-01-20 22 views
6

Ho bisogno di fare questo effetto con php. So che c'è IMG_FILTER_PIXELATE nel filtro immagine PHP. Ma ho bisogno che sia più liscio e in rilievo? come in questa immagine:Immagine pixel pixelata?

image

Questo effetto farà alcuna immagine caricata dall'utente diventare pixel e il bordo dell'immagine diventano rosso (lo so IMG_FILTER_EDGEDETECT ma non so come usarlo per cambiare bordo colore).

Non ho idea di come fare questo.

+3

L'immagine hai collegato sembra provenire da un filtro di Photoshop. Probabilmente non riuscirai a replicare quello sguardo esatto senza una programmazione di manipolazione delle immagini piuttosto hardcore. Puoi creare una serie di immagini campione, una "prima" e una "dopo" che dimostri l'effetto esatto che stai cercando? – Charles

+0

Per l'effetto pixel, penso che sia come il filtro patchwork in Photoshop. Come lo posso fare? – just2cya

+0

http://www.flickr.com/photos/[email protected]/6729984045/ Io creo questo usando la trama del filtro patchwork di Photoshop, e per l'immagine di fondo, utilizzo il colore di sostituzione. – just2cya

risposta

14

Come l'ultima risposta è stata teorica e sembrava essere non abbastanza, ho creato un esempio pratico:
Nota: Questo è di gran lunga dall'effetto "ideale" e dalla perfetta funzione di effetto pixel, ma fa il suo lavoro. Sentiti libero di modificarlo in base alle tue esigenze.

<?php 
/* Function to make pixelated images 
* Supported input: .png .jpg .jpeg .gif 
* 
* 
* Created on 24.01.2011 by Henrik Peinar 
*/ 


/* 
* image - the location of the image to pixelate 
* pixelate_x - the size of "pixelate" effect on X axis (default 10) 
* pixelate_y - the size of "pixelate" effect on Y axis (default 10) 
* output - the name of the output file (extension will be added) 
*/ 
function pixelate($image, $output, $pixelate_x = 20, $pixelate_y = 20) 
{ 
    // check if the input file exists 
    if(!file_exists($image)) 
     echo 'File "'. $image .'" not found'; 

    // get the input file extension and create a GD resource from it 
    $ext = pathinfo($image, PATHINFO_EXTENSION); 
    if($ext == "jpg" || $ext == "jpeg") 
     $img = imagecreatefromjpeg($image); 
    elseif($ext == "png") 
     $img = imagecreatefrompng($image); 
    elseif($ext == "gif") 
     $img = imagecreatefromgif($image); 
    else 
     echo 'Unsupported file extension'; 

    // now we have the image loaded up and ready for the effect to be applied 
    // get the image size 
    $size = getimagesize($image); 
    $height = $size[1]; 
    $width = $size[0]; 

    // start from the top-left pixel and keep looping until we have the desired effect 
    for($y = 0;$y < $height;$y += $pixelate_y+1) 
    { 

     for($x = 0;$x < $width;$x += $pixelate_x+1) 
     { 
      // get the color for current pixel 
      $rgb = imagecolorsforindex($img, imagecolorat($img, $x, $y)); 

      // get the closest color from palette 
      $color = imagecolorclosest($img, $rgb['red'], $rgb['green'], $rgb['blue']); 
      imagefilledrectangle($img, $x, $y, $x+$pixelate_x, $y+$pixelate_y, $color); 

     }  
    } 

    // save the image 
    $output_name = $output .'_'. time() .'.jpg'; 

    imagejpeg($img, $output_name); 
    imagedestroy($img); 
} 


pixelate("test.jpg", "testing"); 


?> 

Questa è la funzione di esempio per creare effetti pixel sulle immagini. Ecco un esempio risultati di utilizzare questa funzione:
originale:

Pixelated 5PX:

10px Pixelated:

20px Pixelated:

+0

Oh, grazie. Ma ho bisogno che sia come in \t flickr.com/photos/[email protected]/6729984045, ho creato questo usando la trama del filtro patchwork di Photoshop. In questa immagine, sembra che ogni quadrato sia in rilievo. È possibile? – just2cya

+0

Fondamentalmente sì ... hai bisogno di cambiare l'oscurità dei pixel esterni di un quadrato ... è più un lavoro e purtroppo non ho il tempo di scrivere lo script ora. –

+0

Finalmente utilizzo lo script e aggiungo questo script da http://stackoverflow.com/questions/9106893/php-emboss-with-color/9107056#9107056 Grazie! – just2cya

1

Qui va teoricamente:
avete un'immagine:

RGBRGBRGBRGB
GBRGBRGBRGBR
GBRGBRGBRRGB
BGRGBGRGGRBG

Prendere il colore del primo pixel e impostare lo stesso colore per un quadrato di prossima pixel (sia in basso che a destra). Poi prendi il colore di un quinto pixel (dato che 4 all'inizio hanno già lo stesso colore). Se hai finito per la prima riga, vai su +3 righe e ricomincia.

Così si ottiene:
RRRRGGGBBBB
RRRRGGGBBBB
RRRRGGGBBBB
RRRRGGGBBBB

In PHP è possibile utilizzare le seguenti funzioni per rendere questo:
http://php.net/manual/en/function.imagecolorat.php per selezionare il colore di un pixel
http://php.net/manual/en/function.imagecolorset.php a imposta il colore di un pixel
http://php.net/manual/en/function.imagesx.php ottieni la larghezza dell'immagine
http://php.net/manual/en/function.imagesy.php get altezza dell'immagine

uso per i loop thru i pixel di un'immagine

+0

Ciao, grazie per la tua risposta. Posso fare il colore di sostituzione usando quelle funzioni che hai citato. Ora devo trovare un modo per rendere l'effetto pixellare .. Qualche idea? – just2cya

+0

L'intero post era su come realizzare l'effetto pixellate .... come hai potuto mancarlo? :) Farò un esempio di script con commenti. Aspetta nuove risposte/commenti. –

2

Grazie per la risposta . Ho usato la tua funzione e aggiunto un altro ciclo per cambiare il colore del pixel esterno dei quadrati usando una funzione chiamata imagelinethick in http://www.php.net/manual/en/function.imageline.php.Così è diventato:

<?php 
$image = imagecreatefromjpeg('Penguins.jpg'); 
$imagex = imagesx($image); 
$imagey = imagesy($image); 

$pixelate_y=10; 
$pixelate_x=10; 
$height=$imagey; 
$width=$imagex; 
for($y = 0;$y < $height;$y += $pixelate_y+1) 
{ 
    for($x = 0;$x < $width;$x += $pixelate_x+1) 
    { 
    // get the color for current pixel 
    $rgb = imagecolorsforindex($image, imagecolorat($image, $x, $y)); 

    // get the closest color from palette 
    $color = imagecolorclosest($image, $rgb['red'], $rgb['green'], $rgb['blue']); 

    imagefilledrectangle($image, $x, $y, $x+$pixelate_x, $y+$pixelate_y, $color); 
    } 
} 


for($y = 0;$y < $height;$y += $pixelate_y+1) 
{ 
for($x = 0;$x < $width;$x += $pixelate_x+1) 
{ 
    //make a border line for each square 
    $rgb = imagecolorsforindex($image, imagecolorat($image, $x, $y)); 
    $color = imagecolorclosest($image, 123, 123, 123); 
    imagelinethick($image, $x, $y, $x, $y+$pixelate_y, $color, 1); 
    imagelinethick($image, $x, $y, $x+$pixelate_x, $y, $color, 2); 
}  
} 

function imagelinethick($image, $x1, $y1, $x2, $y2, $color, $thick = 1) 
{ 
    /* this way it works well only for orthogonal lines 
    imagesetthickness($image, $thick); 
    return imageline($image, $x1, $y1, $x2, $y2, $color); 
    */ 
    if ($thick == 1) { 
     return imageline($image, $x1, $y1, $x2, $y2, $color); 
    } 
$t = $thick/2 - 0.5; 
if ($x1 == $x2 || $y1 == $y2) { 
    return imagefilledrectangle($image, round(min($x1, $x2) - $t), round(min($y1, $y2) - $t), round(max($x1, $x2) + $t), round(max($y1, $y2) + $t), $color); 
} 
$k = ($y2 - $y1)/($x2 - $x1); //y = kx + q 
$a = $t/sqrt(1 + pow($k, 2)); 
$points = array(
    round($x1 - (1+$k)*$a), round($y1 + (1-$k)*$a), 
    round($x1 - (1-$k)*$a), round($y1 - (1+$k)*$a), 
    round($x2 + (1+$k)*$a), round($y2 - (1-$k)*$a), 
    round($x2 + (1-$k)*$a), round($y2 + (1+$k)*$a), 
); 
imagefilledpolygon($image, $points, 4, $color); 
return imagepolygon($image, $points, 4, $color); 
} 

header("Content-Type: image/JPEG"); 
imageJPEG($image, "", 75); 

?> 

Il risultato è simile a questo: http://www.flickr.com/photos/[email protected]/6759029339/

ma penso che questo ancora bisogno di qualche miglioramento per renderlo più morbido.

+0

Chiunque può aiutare? – just2cya

0

Questo è il mio tentativo di risolvere il problema.

È possibile modificare la dimensione del blocco pixelato ed è possibile applicare una sfocatura che attenua l'effetto sulle immagini a contrasto elevato. Può essere un lento su immagini di grandi dimensioni con piccole dimensioni di blocco pixelate però.

Gli script memorizzano i colori dei pixel pertinenti in una matrice. Quindi imprime l'immagine, modifica il contrasto come richiesto, pixelizza l'immagine utilizzando la funzione imagefilter() e quindi (se è impostato il miglioramento delle tessere) lo ristampa di nuovo (ciò aumenta l'effetto 3D sui riquadri finali). Se è richiesta la sfocatura, lo script applica la sfocatura gaussiana. Lo script quindi disegna quadrati pieni usando l'array di colori per creare il colorato effetto pixel all'interno dei bordi in rilievo delle piastrelle.

function pixelatemboss($image,$blockwidth=10,$blur=5,$tileenhance="true",$contrast=0,$negate="true") 
{ 
    if($blockwidth>1) 
    { 
     imagefilter($image,IMG_FILTER_CONTRAST,$contrast); 

     for($x=1;$x<imagesx($image);$x=$x+$blockwidth) 
     { 
      for($y=1;$y<imagesy($image);$y=$y+$blockwidth) 
      { 
       $color[$x][$y]=imagecolorat($image,$x,$y); 
      } 
     } 

     imagefilter($image,IMG_FILTER_EMBOSS); 
     imagefilter($image,IMG_FILTER_CONTRAST,$contrast); 
     imagefilter($image,IMG_FILTER_PIXELATE,$blockwidth,false); 
     if($tileenhance=="true") 
     { 
      imagefilter($image,IMG_FILTER_EMBOSS); 
     } 
     for($b=0;$b<$blur;$b++) 
     { 
      imagefilter($image,IMG_FILTER_GAUSSIAN_BLUR); 
     } 
     for($x=1;$x<imagesx($image);$x=$x+$blockwidth) 
     { 
      for($y=1;$y<imagesy($image);$y=$y+$blockwidth) 
      { 
       $rgb=$color[$x][$y]; 
       $r = ($rgb >> 16) & 0xFF; 
       $g = ($rgb >> 8) & 0xFF; 
       $b = $rgb & 0xFF; 
       $col=imagecolorallocate($image,$r,$g,$b); 
       imagefilledrectangle($image,$x,$y,$x+($blockwidth-2),$y+($blockwidth-2),$col); 
      } 
     } 
    } 
    return $image; 
} 
0

Nota per PHP 5.4 e fino è necessario utilizzare:

imageJPEG($image, NULL, 75); 

Non è più possibile specificare NULL utilizzando un doppio apice (come in questo esempio):

imageJPEG($image, "", 75); 
Problemi correlati