16

使用 ImageMagick 或 GD 库将图像裁剪或遮罩为圆形的最佳方法是什么?(注意,解决方案存在于“其他”问答网站上,但 StackOverflow 上不存在)

4

5 回答 5

52

这是 ImageMagick 的一种方法,可以在不使用掩码的情况下完成此操作:

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

沃尔特 替代文字

于 2009-06-16T04:27:22.353 回答
2

对于那些需要在纯PHP 中使用 Imagick执行此操作的人,您需要参考这个问题:circleize an image with imagick

希望这会有所帮助。

J。

于 2013-12-03T10:06:11.820 回答
2

对于那些想要 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);
于 2016-04-30T18:11:31.507 回答
0

对于那些想要基于 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()。

于 2016-04-06T06:19:53.213 回答
0

如果要对图像的角进行圆形处理,可以使用此功能。要制作圆形图像,需要将 $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;
}
于 2017-11-21T21:01:36.843 回答