php 剪切图片为圆形,PHP 裁剪图片成圆形、不规则形状

第一种方法

= $radius && $x <= ($w - $radius)) || ($y >= $radius && $y <= ($h - $radius))) {

imagesetpixel($img, $x, $y, $rgbColor); // 不在四角的范围内,直接画

} else { // 在四角的范围内选择画

// 上左

$yx = $r; // 圆心X坐标

$yy = $r; // 圆心Y坐标

if (((($x - $yx) * ($x - $yx) + ($y - $yy) * ($y - $yy)) <= ($r * $r))) {

imagesetpixel($img, $x, $y, $rgbColor);

}

// 上右

$yx = $w - $r; // 圆心X坐标

$yy = $r; // 圆心Y坐标

if (((($x - $yx) * ($x - $yx) + ($y - $yy) * ($y - $yy)) <= ($r * $r))) {

imagesetpixel($img, $x, $y, $rgbColor);

}

// 下左

$yx = $r; // 圆心X坐标

$yy = $h - $r; // 圆心Y坐标

if (((($x - $yx) * ($x - $yx) + ($y - $yy) * ($y - $yy)) <= ($r * $r))) {

imagesetpixel($img, $x, $y, $rgbColor);

}

// 下右

$yx = $w - $r; // 圆心X坐标

$yy = $h - $r; // 圆心Y坐标

if (((($x - $yx) * ($x - $yx) + ($y - $yy) * ($y - $yy)) <= ($r * $r))) {

imagesetpixel($img, $x, $y, $rgbColor);

}

}

}

}

return $img;

}

function cropImg($img, $axisx, $axisy) {

$width = imagesx($img);

$height = imagesy($img);

$setRatio = $axisx / $axisy;

$curRatio = $width / $height;

if ($setRatio > $curRatio) {

$resizeX = $width;

$resizeY = $resizeX * $axisy / $axisx;

$x = 0;

$y = ($height - $resizeY) / 2;

} elseif ($setRatio < $curRatio) {

$resizeY = $height;

$resizeX = $resizeY * $axisx / $axisy;

$x = ($width - $resizeX) / 2;

$y = 0;

} else {

$resizeX = $width;

$resizeY = $height;

$x = $y = 0;

}

$im = imagecreatetruecolor($resampleX, $resampleY);

imagecopyresampled($im, $img, 0, 0, $x, $y, $resampleX, $resampleY, $resampleX, $resampleY);

imagedestroy($img);

return $im;

}

$url = 'https://upload-images.jianshu.io/upload_images/8396841-829819a83d4a77e4.jpg';

$img = createImg($url); // 创建GD图像资源

$img = cropImg($img, 1, 1); // 为了美观居中裁剪成正方形

$img = roundImgs($img); // 将四个角画成透明的

imagepng($img, './roundBirds.png');

imagedestroy($img);

原图 = 47aab61cfc8205bd093aa913b863de4b.png                                     裁剪后 = 8d8bd390a406ef265d3f86a9db363912.png

第二种方法:使用PHP Imagick库进行图片圆角处理,Imagick是自带的图片圆角处理,在执行效率上也比GD的要胜上一筹。

/**

* Imagick裁剪圆形图片

*

* @param strimg $imgPath 图片路径

* @param string $saveName 保存路径

* @return source 生成的图片

*/

function roundImg($imgPath, $saveName){

$image = new Imagick($imgPath);

$image->setImageFormat('png');

$width = $image->getImageWidth();

$height = $image->getImageHeight();

$image->roundCorners($width/2, $height/2);

$saveName = $saveName ? : substr(md5(time()), 0, 5).'.png';

$image->writeImage($saveName);

$image->destroy();

}

第三种方法:使用PHP GD库进行处理。速度:快。缺点:imagecopyresampled时透明部分会失真,要缩放只能用imagecopyresesize

/**

* 处理圆角图片

* @param srting $imgpath 源图片的路径

* @return [type] [description]

*/

function roundedCorners($imgpath){

list($width,$height,$type) = getimagesize($imgpath);//获取上传图片大小

if ($width != $height) {//如果上传图片不是正方形,取最小宽度作为最终生成图的大小

if ($width > $height) {

$imsize = $height;

} else {

$imsize = $width;

}

}

$im = imagecreatetruecolor($imsize, $imsize);//这里创建第一个图像

$white = imagecolorallocate($im, 255, 255, 255);// 随便取两个颜色,这里取黑色和白色

$black = imagecolorallocate($im, 0, 0, 0);

imagefill($im, 0, 0, $white);//将图片填充为白色

imagefilledellipse($im, $imsize/2, $imsize/2, $imsize, $imsize, $black);//然后再图片中间画一个黑色的圆

imagecolortransparent($im, $black);//将黑色设为透明的,则现在四个角是白色的,然后中间是透明的

switch ($type) {

case '2':

$img = imagecreatefromjpeg($imgpath);//这里创建的是第二个图像

break;

default:

$img = imagecreatefrompng($imgpath);//这里创建的是第二个图像

break;

}

$final = imagecreatetruecolor($imsize, $imsize);//再创建一个图像,第三个图像

imagecopyresampled($final, $img, 0, 0, ($width-$imsize)/2, ($height-$imsize)/2, $imsize, $imsize, $imsize, $imsize);//先将第二个图像(图片)压在空白的图像上,根据最小宽度,居中裁剪,成为第四个图像

imagecopymerge($final, $im, 0, 0, 0, 0, $imsize, $imsize, 100);//再将第一个图像压在第四个图像上,由于中间是透明的,所以现在图像上中间是图片,四个角都是白色的,第五个图

imagecolortransparent($im, $white);//然后将白色设置为透明的,现在这个图四个角是透明的,然后中间是黑色的

imagecopymerge($im, $final, 0, 0, 0, 0, $imsize, $imsize, 100);//将第五个图压在最后的图像上,就可以得到最后的圆形的图了

return $im;//返回图片

}

要裁剪不规则图形则需要借助另外的图片来完成任务。需要借助二值图作为模板图,或者给出的模板图片上,要抠出来的部分须为不透明的,要去掉的部分则为透明的,传入模板图片和原始图片地址,返回一个图片资源。

/**

* 根据给出的模板抠图

* @param string $templateImgUrl 模板图片地址

* @param string $userImgUrl 原始图片地址

* @return source $img 图片资源

*/

function createImg($srcFile) {

$data = getimagesize($srcFile);

switch ($data['2']) {

case 1:

$im = imagecreatefromgif($srcFile);

break;

case 2:

$im = imagecreatefromjpeg($srcFile);

break;

case 3:

$im = imagecreatefrompng($srcFile);

break;

case 6:

$im = imagecreatefromwbmp($srcFile);

break;

}

return $im;

}

function cropImgByTemplate($templateImgUrl, $userImgUrl) {

list($w, $h) = getimagesize($userImgUrl);

$uimg = createImg($userImgUrl);

$tempImg = imagecreatefrompng($templateImgUrl);

list($width,$height) = getimagesize($templateImgUrl);

$uim = imagecreatetruecolor($width, $height); // 将用户图片的尺寸大小缩放到模板的大小方便裁剪

imagecopyresampled($uim, $uimg, 0, 0, 0, 0, $width, $height, $w, $h);

$img = imagecreatetruecolor($width, $height); // 创建一个底图,大小和模板一致

imagesavealpha($img, true); // 设置alpha通道为true,显示透明部分

$bg = imagecolorallocatealpha($img, 255, 255, 255, 127); // 摄取一个透明的颜色

imagefill($img, 0, 0, $bg); // 将透明颜色填满底图,得到一张全透明的图片

for ($i=0; $i < $width; $i++) { // 遍历图片的像素点

for ($j=0; $j < $height; $j++) {

$rgb = imagecolorat($tempImg, $i, $j); // 获取模板上某个点的色值

if (!$rgb) { // 不是透明的

$color = imagecolorat($uim, $i, $j); // 在用户的图片上对应的地方取色值

imagesetpixel($img, $i, $j, $color); // 在透明底图上画出要裁剪出来的部分

}

}

}

return $img;

}

$tempUrl = 'https://upload-images.jianshu.io/upload_images/8396841-50c151628048a0cf.png';

$url = 'https://upload-images.jianshu.io/upload_images/8396841-829819a83d4a77e4.jpg';

$img = cropImgByTemplate($tempUrl, $url);

imagepng($img, './test.png');

imagedestroy($img);

模板图==16249494c5f3c505f516fa9d98ceaa2f.png   原图 == 47aab61cfc8205bd093aa913b863de4b.png     裁剪后 == 8c4bf3748393fa2656c71c8ff282d47c.png

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值