2009-06-16 15 views
13

Jaki jest najlepszy sposób przycinania lub maskowania obrazu w kolisty kształt przy użyciu bibliotek ImageMagick lub GD? (Należy zauważyć, istnieje rozwiązanie "inne" Q & miejscach A, ale nie StackOverflow)Przycinanie lub maskowanie obrazu w kręgu

+0

Co jest nie tak z innymi rozwiązaniami? – alex

+2

Nie można ich bezpośrednio połączyć i wymagają rejestracji, aby wyświetlić odpowiedzi, dlatego nie możemy udostępnić rozwiązania osobie, której pomagam. – pix0r

+0

Jeśli to ExpertSexChange, czy kiedykolwiek przewinąłeś się na sam dół? Odpowiedzi są tam. Przydatna sztuczka (czasami). – alex

Odpowiedz

48

tutaj jedną z ImageMagick które acomplish bez stosowania maski:

convert -size 200x200 xc:none -fill walter.jpg -draw "circle 100,100 100,1" circle_thumb.png 

walter alt text

+0

To działa, dziękuję. Byłoby miło zobaczyć to również w GD;) – pix0r

+4

+1 za dużego lebowskiego – Steven

+0

+1 za walta, stary;) – kirugan

2

Dla tych, którzy potrzebują tego w czystym PHP przy użyciu Imagick, trzeba będzie odnieść się do tego pytania: circularize an image with imagick

Mam nadzieję, że to pomoże.

J.

0

Dla tych, którzy chcą węzeł/js oparte rozwiązanie, można utworzyć okrągły uprawy w określonych współrzędnych za pomocą node-gm tak:

gm(original) 
    .crop(233, 233,29,26) 
    .resize(size, size) 
    .write(output, function(err) { 
     gm(size, size, 'none') 
     .fill(output) 
     .drawCircle(size/2,size/2, size/2, 0) 
     .write(output, function(err) { 
      console.log(err || 'done'); 
     }); 
    }); 

Można użyć lib jak JCrop (demo), aby zezwolić użytkownikowi na przycięcie obrazu na przedniej stronie i przekazanie współrzędnych (w, h, x, y) do przycinania().

2

Dla tych, którzy chcą rozwiązania w PHP, zapewniając obraz już przycięty do kręgu:

// convert the picture 
    $w = 640; $h=480; // original size 
    $original_path="/location/of/your/original-picture.jpg"; 
    $dest_path="/location/of/your/picture-crop-transp.png"; 
    $src = imagecreatefromstring(file_get_contents($original_path)); 
    $newpic = imagecreatetruecolor($w,$h); 
    imagealphablending($newpic,false); 
    $transparent = imagecolorallocatealpha($newpic, 0, 0, 0, 127); 
    $r=$w/2; 
    for($x=0;$x<$w;$x++) 
     for($y=0;$y<$h;$y++){ 
      $c = imagecolorat($src,$x,$y); 
      $_x = $x - $w/2; 
      $_y = $y - $h/2; 
      if((($_x*$_x) + ($_y*$_y)) < ($r*$r)){ 
       imagesetpixel($newpic,$x,$y,$c); 
      }else{ 
       imagesetpixel($newpic,$x,$y,$transparent); 
      } 
     } 
    imagesavealpha($newpic, true); 
    imagepng($newpic, $dest_path); 
    imagedestroy($newpic); 
    imagedestroy($src); 
+0

Działa! Dziękuję! –

0

Można użyć tej funkcji, jeśli chcesz kołowych narożniki obrazu. Aby utworzyć obraz koła, należy ustawić Promień $ na 50%; Jeśli $ source_url jest kwadratem, wyjście będzie kołem, w przeciwnym razie będzie owalne. Wynik będzie plikiem PNG z przezroczystym tłem.

public function Crop_ByRadius($source_url,$destination_url="",$Radius="0px" ,$Keep_SourceFile = TRUE){ 

    /* 
     Output File is png, Because for crop we need transparent color 

     if success :: this function returns url of Created File 
     if Fial :: returns FALSE 

     $Radius Input Examples :: 
          100  => 100px      
          100px => 100px      
          50%  => 50%     
    */ 

    if(!file_exists($source_url) || $Radius == NULL) 
     return FALSE; 

    if($destination_url == NULL || $destination_url == "") $destination_url = $source_url; 


    $PathInfo = pathinfo($destination_url); 
    $destination_url = $PathInfo['dirname'].DIRECTORY_SEPARATOR.$PathInfo['filename'].".png"; 

    $ImageInfo = getimagesize($source_url); 
    $w = $ImageInfo[0]; 
    $h = $ImageInfo[1]; 
    $mime = $ImageInfo['mime']; 

    if($mime != "image/jpeg" && $mime != "image/jpg" && $mime != "image/png") 
     return FALSE; 

    if(strpos($Radius,"%") !== FALSE){ 
     //$Radius by Cent 
     $Radius = intval(str_replace("%","",$Radius)); 
     $Smallest_Side = $w <= $h ? $w : $h; 
     $Radius = $Smallest_Side * $Radius/100; 

    }else{ 
     $Radius = strtolower($Radius); 
     $Radius = str_replace("px","",$Radius); 
    } 

    $Radius = is_numeric($Radius) ? intval($Radius) : 0; 

    if($Radius == 0) return FALSE; 

    $src = imagecreatefromstring(file_get_contents($source_url)); 
    $newpic = imagecreatetruecolor($w,$h); 
    imagealphablending($newpic,false); 
    $transparent = imagecolorallocatealpha($newpic, 0, 0, 0, 127); 
    //$transparent = imagecolorallocatealpha($newpic, 255, 0, 0, 0);//RED For Test 

    $r = $Radius/2; 

    /********************** Pixel step config ********************************/ 

    $Pixel_Step_def = 0.4;//smaller step take longer time! if set $Pixel_Step=0.1 result is better than $Pixel_Step=1 but it take longer time! 

    //We select the pixels we are sure are in range, to Take up the bigger steps and shorten the processing time 

    $Sure_x_Start = $Radius +1; 
    $Sure_x_End = $w - $Radius -1; 
    $Sure_y_Start = $Radius +1; 
    $Sure_y_End = $h - $Radius -1; 
    if($w <= $h){ 
     //We want to use the larger side to make processing shorter 
     $Use_x_Sure = FALSE; 
     $Use_y_Sure = TRUE; 
    }else{ 
     $Use_x_Sure = TRUE; 
     $Use_y_Sure = FALSE; 
    } 
    /********************** Pixel step config END********************************/ 


    $Pixel_Step = $Pixel_Step_def; 
    for($x=0; $x < $w ; $x+=$Pixel_Step){ 

     if($Use_x_Sure && $x > $Sure_x_Start && $x < $Sure_x_End) $Pixel_Step = 1;else $Pixel_Step = $Pixel_Step_def; 

     for($y=0; $y < $h ; $y+=$Pixel_Step){ 
      if($Use_y_Sure && $y > $Sure_y_Start && $y < $Sure_y_End) $Pixel_Step = 1;else $Pixel_Step = $Pixel_Step_def; 

      $c = imagecolorat($src,$x,$y); 

      $_x = ($x - $Radius) /2; 
      $_y = ($y - $Radius) /2; 
      $Inner_Circle = ((($_x*$_x) + ($_y*$_y)) < ($r*$r)); 
      $top_Left = ($x > $Radius || $y > $Radius) || $Inner_Circle; 

      $_x = ($x - $Radius) /2 - ($w/2 - $Radius); 
      $_y = ($y - $Radius) /2; 
      $Inner_Circle = ((($_x*$_x) + ($_y*$_y)) < ($r*$r)); 
      $top_Right = ($x < ($w - $Radius) || $y > $Radius) || $Inner_Circle; 

      $_x = ($x - $Radius) /2; 
      $_y = ($y - $Radius) /2 - ($h/2 - $Radius); 
      $Inner_Circle = ((($_x*$_x) + ($_y*$_y)) < ($r*$r)); 
      $Bottom_Left = ($x > $Radius || $y < ($h - $Radius)) || $Inner_Circle; 

      $_x = ($x - $Radius) /2 - ($w/2 - $Radius); 
      $_y = ($y - $Radius) /2 - ($h/2 - $Radius); 
      $Inner_Circle = ((($_x*$_x) + ($_y*$_y)) < ($r*$r)); 
      $Bottom_Right = ($x < ($w - $Radius) || $y < ($h - $Radius)) || $Inner_Circle; 

      if($top_Left && $top_Right && $Bottom_Left && $Bottom_Right){ 

       imagesetpixel($newpic,$x,$y,$c); 

      }else{ 
       imagesetpixel($newpic,$x,$y,$transparent); 
      } 

     } 
    } 


    if(!$Keep_SourceFile && $source_url != $destination_url){ 
     unlink($source_url); 
    } 


    imagesavealpha($newpic, true); 
    imagepng($newpic, $destination_url); 
    imagedestroy($newpic); 
    imagedestroy($src); 


    return $destination_url; 
}