2012-01-20 49 views
6

Tôi cần tạo hiệu ứng này bằng php. Tôi biết rằng có IMG_FILTER_PIXELATE trong bộ lọc hình ảnh PHP. Nhưng tôi cần nó mượt mà và nổi hơn? như trong hình ảnh này:pixel hình ảnh PHP?

image

Hiệu ứng này sẽ làm cho bất kỳ hình ảnh được tải lên bởi người sử dụng trở thành hiện tượng pixel và cạnh của hình ảnh trở nên đỏ (Tôi biết IMG_FILTER_EDGEDETECT nhưng tôi không biết làm thế nào để sử dụng nó để thay đổi cạnh màu).

Tôi không biết làm cách nào để thực hiện việc này.

+3

Hình ảnh bạn liên kết trông giống như nó đến từ một bộ lọc Photoshop. Bạn có lẽ sẽ không thể tái tạo lại cái nhìn chính xác mà không có một số chương trình thao tác hình ảnh đẹp mắt. Bạn có thể tạo một tập các hình ảnh mẫu, một "trước" và một "sau" thể hiện hiệu ứng chính xác mà bạn đang tìm kiếm không? – Charles

+0

Đối với hiệu ứng pixelate, tôi nghĩ nó giống như bộ lọc chắp vá trong photoshop. Làm thế nào tôi có thể làm điều đó? – just2cya

+0

http://www.flickr.com/photos/[email protected]/6729984045/ Tôi tạo điều này bằng cách sử dụng kết cấu bộ lọc chắp vá Photoshop, và đối với hình ảnh dưới cùng, tôi sử dụng màu thay thế. – just2cya

Trả lời

14

Như câu trả lời cuối cùng là lý thuyết và dường như là không đủ, tôi đã tạo ra một ví dụ thực tế:
Lưu ý: Đây là xa từ "hiệu ứng" hoàn hảo và chức năng hiệu ứng pixelate hoàn hảo, nhưng nó thực hiện công việc. Vui lòng chỉnh sửa nó theo nhu cầu của riêng bạn.

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


?> 

Đây là chức năng ví dụ để tạo hiệu ứng pixelated trên hình ảnh. Dưới đây là một ví dụ kết quả của việc sử dụng chức năng này:
gốc:

pixelated 5px:

10px pixelated:

20px pixelated:

+0

Ồ, cảm ơn. Nhưng tôi cần nó giống như trong \t flickr.com/photos/[email protected]/6729984045, tôi đã tạo ra điều này bằng cách sử dụng kết cấu bộ lọc chắp vá của Photoshop. Trong bức ảnh này, có vẻ như mỗi hình vuông được dập nổi. là nó có thể? – just2cya

+0

Về cơ bản yea ... bạn cần phải thay đổi bóng tối của các điểm ảnh bên ngoài của một hình vuông ... đó là nhiều công việc tho và tôi buồn bã không có thời gian để viết kịch bản bây giờ. –

+0

Cuối cùng tôi đã sử dụng tập lệnh của bạn và thêm tập lệnh này từ http://stackoverflow.com/questions/9106893/php-emboss-with-color/9107056#9107056 Cảm ơn bạn! – just2cya

1

Ở đây đi theo lý thuyết:
Bạn có một hình ảnh:

RGBRGBRGBRGB
GBRGBRGBRGBR
GBRGBRGBRRGB
BGRGBGRGGRBG

Lấy màu của pixel đầu tiên và thiết lập các màu sắc tương tự cho một hình vuông cạnh pixel (cả xuống và phải). Sau đó, lấy màu của một điểm ảnh thứ 5 (như 4 điểm ở đầu đã có cùng màu). Nếu bạn làm xong hàng đầu tiên, hãy giảm +3 hàng và bắt đầu lại.

Vì vậy, bạn nhận được:
RRRRGGGBBBB
RRRRGGGBBBB
RRRRGGGBBBB
RRRRGGGBBBB

Trong PHP bạn có thể sử dụng các chức năng sau để làm điều này:
http://php.net/manual/en/function.imagecolorat.php để chọn màu của một điểm ảnh
http://php.net/manual/en/function.imagecolorset.php để đặt màu của pixel là
http://php.net/manual/en/function.imagesx.php nhận chiều rộng hình ảnh
http://php.net/manual/en/function.imagesy.php get chiều cao hình ảnh

sử dụng cho vòng qua các điểm ảnh của một hình ảnh

+0

Xin chào, cảm ơn bạn đã trả lời. Tôi có thể làm cho màu thay thế bằng cách sử dụng những chức năng mà bạn đã đề cập. Bây giờ tôi phải tìm một cách để tạo hiệu ứng pixellate .. Bất kỳ ý tưởng nào? – just2cya

+0

Toàn bộ bài viết về cách tạo hiệu ứng pixellate .... làm thế nào bạn có thể bỏ lỡ nó? :) Tôi sẽ tạo một kịch bản mẫu với nhận xét. Chờ câu trả lời/bình luận mới. –

2

Cảm ơn bạn đã trả lời của bạn . Tôi đã sử dụng hàm của bạn và thêm một vòng lặp khác để thay đổi màu của pixel ngoài của hình vuông bằng cách sử dụng hàm có tên imagelinethick trong http://www.php.net/manual/en/function.imageline.php.Vì vậy, nó đã trở thành:

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

?> 

Kết quả là như thế này: http://www.flickr.com/photos/[email protected]/6759029339/

Nhưng tôi nghĩ rằng điều này vẫn cần một số cải tiến để làm cho nó mượt mà hơn.

+0

Bất cứ ai cũng có thể giúp đỡ? – just2cya

0

Đây là nỗ lực của tôi về vấn đề này.

Bạn có thể thay đổi kích thước khối pixelate và bạn có thể áp dụng hiệu ứng làm mờ hiệu ứng trên hình ảnh có độ tương phản cao. Có thể là một hình ảnh lớn chậm với kích thước khối pixelate nhỏ mặc dù.

Các tập lệnh lưu trữ màu của các pixel có liên quan trong một mảng. Sau đó nó dập nổi hình ảnh, làm thay đổi độ tương phản theo yêu cầu, pixelates hình ảnh bằng cách sử dụng chức năng imagefilter() và sau đó (nếu tăng cường gạch được thiết lập) dập nổi nó một lần nữa (điều này làm tăng hiệu ứng 3D trên gạch cuối cùng). Nếu blur được yêu cầu script thì áp dụng hiệu ứng Gaussian blur. Sau đó, tập lệnh sẽ vẽ các hình vuông được lấp đầy bằng cách sử dụng mảng màu để tạo hiệu ứng pixelated đầy màu sắc trong các đường viền gạch nổi.

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

Lưu ý cho php 5.4 và lên bạn cần phải sử dụng:

imageJPEG($image, NULL, 75); 

Bạn không còn có thể chỉ định NULL bằng cách sử dụng một dấu nháy kép (như ví dụ này):

imageJPEG($image, "", 75); 
Các vấn đề liên quan