Qual è il modo migliore per ritagliare o mascherare un'immagine in una forma circolare, utilizzando le librerie ImageMagick o GD? (Nota, la soluzione esiste "altri" Q & siti A, ma non StackOverflow)Ritaglia o maschera un'immagine in un cerchio
risposta
Ecco un modo con ImageMagick che compire questo senza usare una maschera:
convert -size 200x200 xc:none -fill walter.jpg -draw "circle 100,100 100,1" circle_thumb.png
Per coloro che hanno bisogno di fare questo in puro PHP utilizzando Imagick, sarà necessario fare riferimento a questa domanda: circularize an image with imagick
Spero che questo possa essere d'aiuto.
J.
Per chi vuole un nodo/js soluzione basata, è possibile creare un raccolto circolare coordinate specificate utilizzando node-gm come questo:
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');
});
});
è possibile utilizzare un lib come JCrop (demo) per consentire all'utente di ritagliare l'immagine sul front-end e passare le coordinate (w, h, x, y) in crop().
Per chi vuole una soluzione in PHP, che fornisce il quadro già ritagliata in un circolo:
// 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);
Funziona! Grazie! –
È possibile utilizzare questa funzione se si vuole circolare gli angoli di un'immagine. Per rendere l'immagine circolare, è necessario impostare $ Raggio al 50%; Se $ source_url è un quadrato, l'output sarà il cerchio, altrimenti sarà ovale. L'output sarà un file PNG con sfondo trasparente.
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;
}
Cosa c'è di sbagliato con le altre soluzioni? – alex
Non sono direttamente collegabili e richiedono la registrazione per visualizzare le risposte, quindi non sono in grado di condividere la soluzione con la persona che sto aiutando. – pix0r
Se è ExpertSexChange, hai mai fatto scorrere verso il basso fino in fondo? Le risposte ci sono Trucco utile (a volte). – alex