使用ImageMagick或GD库将图像裁剪或遮罩为圆形的最佳方法是什么?(注意,解决方案存在于“其他”问答网站,但不存在于StackOverflow)
ddrv8njm1#
这里有一种方法与ImageMagick,将完成这一点,而不使用遮罩:
convert -size 200x200 xc:none -fill walter.jpg -draw "circle 100,100 100,1" circle_thumb.png
rsl1atfo2#
对于那些需要使用Imagick在纯PHP中执行此操作的用户,您需要参考以下问题:用imagick圆形化图像希望这会有帮助。J。
lh80um4z3#
对于那些想要PHP解决方案的人,提供已经裁剪成圆形的图片:
// 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);
uidvcgyl4#
对于那些想要基于node/js的解决方案的用户,可以使用node-gm在指定坐标处创建一个圆形裁剪,如下所示:
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'); }); });
您可以使用JCrop(demo)这样的库来允许用户在前端裁剪图像,并将坐标(w,h,x,y)传递给crop()。
ldfqzlk85#
如果你想把图像的边角画成圆形,可以使用这个功能,要画成圆形图像,需要把$Radius设为50%;如果$source_url是一个正方形,则输出为圆形,否则为椭圆形,输出为背景透明的PNG文件。
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; }
aamkag616#
以下是基于掩码GD的解决方案,称为imageRemoveOuterCircle:
GD
imageRemoveOuterCircle
// From https://stackoverflow.com/a/23215738/2590508 function hexColorAllocate($im,$hex){ $hex = ltrim($hex,'#'); $r = hexdec(substr($hex,0,2)); $g = hexdec(substr($hex,2,2)); $b = hexdec(substr($hex,4,2)); return imagecolorallocate($im, $r, $g, $b); } function imageRemoveOuterCircle(&$image,$width=null,$height=null){ // 2 arbitrary colors for transparency ; can be redefined if needed $transparentColor1="8d5ca4"; $transparentColor2="8d5ca5"; if(is_null($width)){ $width=imagesx($image); } if(is_null($height)){ $height=imagesy($image); } $mask=imagecreatetruecolor($width, $height); imagefilledrectangle( $mask, 0, 0, $width, $height, hexColorAllocate($mask,$transparentColor1) ); imagefilledellipse( $mask, $width/2, $height/2, $width, $height, hexColorAllocate($mask,$transparentColor2) ); imagecolortransparent($mask,hexColorAllocate($mask,$transparentColor2)); imagecopy( $image, $mask, 0, 0, 0, 0, $width, $height ); imagedestroy($mask); imagecolortransparent($image,hexColorAllocate($image,$transparentColor1)); }
6条答案
按热度按时间ddrv8njm1#
这里有一种方法与ImageMagick,将完成这一点,而不使用遮罩:
rsl1atfo2#
对于那些需要使用Imagick在纯PHP中执行此操作的用户,您需要参考以下问题:用imagick圆形化图像
希望这会有帮助。
J。
lh80um4z3#
对于那些想要PHP解决方案的人,提供已经裁剪成圆形的图片:
uidvcgyl4#
对于那些想要基于node/js的解决方案的用户,可以使用node-gm在指定坐标处创建一个圆形裁剪,如下所示:
您可以使用JCrop(demo)这样的库来允许用户在前端裁剪图像,并将坐标(w,h,x,y)传递给crop()。
ldfqzlk85#
如果你想把图像的边角画成圆形,可以使用这个功能,要画成圆形图像,需要把$Radius设为50%;如果$source_url是一个正方形,则输出为圆形,否则为椭圆形,输出为背景透明的PNG文件。
aamkag616#
以下是基于掩码
GD
的解决方案,称为imageRemoveOuterCircle
: