2012-01-20 4 views
6

私はこの効果をPHPで行う必要があります。 PHPの画像フィルタにIMG_FILTER_PIXELATEがあることを知っています。しかし、私はそれが滑らかで浮き彫りにする必要がありますか?この効果PHPイメージpixelate?

image

ユーザーによってアップロードされた画像は、ピクセル化になるようと画像のエッジが赤になる(私はIMG_FILTER_EDGEDETECTを知っているが、私はエッジを変更するためにそれを使用する方法がわからないだろう。この画像のように色)。

どうすればいいか分かりません。ここで

+3

をイメージPhotoshopのフィルタのように見えます。かなりハードコアの画像操作プログラミングがなければ、その正確な外観を再現することはできません。あなたは探している正確な効果を示す "前"と "後"のサンプル画像を作成できますか? – Charles

+0

pixelate効果については、Photoshopのパッチワークフィルターのようだと思います。どうやってやるの? – just2cya

+0

http://www.flickr.com/photos/52700219NN6/6729984045/ 私はこれをPhotoshopパッチワークフィルタテクスチャを使用して作成し、下の画像では色を置き換えます。 – just2cya

答えて

14

のピクセルスルーforループhttp://php.net/manual/en/function.imagesy.php画像の高さを取得する

使用が足りないように見えた、私は実用的な例を作成しました:
注:これは遠いです「理想的」な完璧なピクセル効果関数からのものですが、それはその仕事です。自分の必要に応じて自由に編集してください。

<?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"); 


?> 

これは、イメージにピクセル効果を作成する関数の例です。 ここでは、この機能を使用した結果の一例です:
オリジナル:

ピクセル化5pxの:

ピクセル化10pxの:

ピクセル化20ピクセル:

+0

ああ、ありがとう。しかし、私は\t のようにする必要がありますflickr.com/photos/[email protected]/6729984045、私はPhotoshopのパッチワークのフィルタテクスチャを使用してこれを作成しました。この図では、各正方形がエンボス加工されているようです。出来ますか? – just2cya

+0

基本的には正に...正方形の外側のピクセルの暗さを変える必要があります...それはもっとうまくいくので、今はスクリプトを書く時間がありません。 –

+0

私は最終的にあなたのスクリプトを使用し、http://stackoverflow.com/questions/9106893/php-emboss-with-color/9107056#9107056からこのスクリプトを追加していただきありがとうございます! – just2cya

1

理論的に行く:
あなたがイメージを持っている:

RGBRGBRGBRGB
GBRGBRGBRGBR
GBRGBRGBRRGB
BGRGBGRGGRBG

は、最初のピクセルの色を取ると、次の正方形のために同じ色を設定しますピクセル(上下両方とも)。その後、5番目のピクセルの色を取ります(最初は4つの色が同じ色です)。最初の行が終了したら、+3行下に戻り、もう一度始めます。だから、

あなたが得る:
RRRRGGGBBBB
RRRRGGGBBBB
RRRRGGGBBBB
RRRRGGGBBBB

PHPで

あなたがこれを行うために、以下の機能を使用することができます。
http://php.net/manual/en/function.imagecolorat.phpは、ピクセルの色を選択するために
http://php.net/manual/en/function.imagecolorset.phpへピクセルの色を設定する
http://php.net/manual/en/function.imagesx.php画像を取得する
最後の答えは、理論的だったと、画像

+0

こんにちは、あなたの答えに感謝します。あなたが言及したそれらの関数を使って色を置き換えることができます。今私はpixellate効果を作る方法を見つける必要があります..任意のアイデア? – just2cya

+0

投稿全体がpixellate効果を作り出す方法についてでした....どのようにそれを見逃すことができますか? :) コメント付きのサンプルスクリプトを作成します。新しい回答/コメントを待ちます。 –

2

は、あなたの答えをありがとうは、 。私はあなたの関数を使用してhttp://www.php.net/manual/en/function.imageline.phpのimagelinethickという関数を使って四角形の外側のピクセルの色を変更する別のループを追加しました。だから、となりました:

<?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); 

?> 

結果はこのようなものです:http://www.flickr.com/photos/[email protected]/6759029339/

しかし、私は、これはまだそれがよりスムーズにするために、いくつかの改善が必要だと思います。

+0

誰でも手伝いできますか? – just2cya

0

これは私の問題です。

ピクセルサイズのブロックサイズを変更することができ、高コントラストの画像で効果を柔らかくするぼかしを適用できます。小さいピクセルサイズのブロックサイズで大きな画像では遅くなることがあります。

スクリプトは、関連するピクセルの色を配列に格納します。画像をエンボスし、必要に応じてコントラストを変更し、imagefilter()関数を使用して画像をピクセル化してから(タイルエンハンスが設定されている場合)、再度エンボスします(これにより、最終タイルの3D効果が増加します)。ぼかしが必要な場合、スクリプトはガウスのぼかしを適用します。スクリプトは、カラー配列を使用して塗りつぶした四角形を描画して、エンボス加工されたタイルの枠内にカラフルなピクセル効果を作成します。

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

あなたが使用する必要がPHP 5.4とアップのための注意:

imageJPEG($image, NULL, 75); 

あなたは、もはや(この例のように)二重引用符を使用してNULLを指定することができます

imageJPEG($image, "", 75); 
関連する問題