php Gd库处理合成图片 生成圆角图
png分为png-8、png-24、png-32
当使用imagepng、imagejpeg输出含有PNG-8图片时通道会消失,png-24图片不会发生这个问题;
应该为避免这种情况,应该先把png-8的图片转换成jpg形式,这样颜色通道就能保存下来;
合成:
pubilc function Composite(){ //$this->pic_base;底图 //$this->pic;合成图 //$this->radius;圆角弧度 //$this->x;合成图 X位置 //$this->y;合成图 Y位置 //$this->width;改变合成图的尺寸 //$this->height;改变合成图的尺寸 //加入底图 $pic_base_ext = pathinfo($this->pic_base);//获取图片信息 switch ($pic_base_ext['extension']) {//根据图片类型 返回图片资源 case 'jpg': $pic_base = imagecreatefromjpeg($this->pic_base); break; case 'jpeg': $pic_base = imagecreatefromjpeg($this->pic_base); break; case 'png': $pic_base = imagecreatefrompng($this->pic_base); break; } list($pic_base_width, $pic_base_height) = getimagesize($this->pic_base); //根据底图的尺寸,创建画布 $image = imagecreatetruecolor($pic_base_width, $pic_base_height); //创建背景颜色 $image_bg = imagecolorallocate($image, 255, 255, 255,127);//127表示透明度,若输出jpg 可以不填,png可以设置 //填充背景颜色 imagefill($image, 0, 0, $image_bg); imagecopyresized($image, $pic_base, 0, 0, 0, 0, $width, $height, $width, $height);//将底图合并到创建的画布 //加入合成图 商品圆角处理 $radius_pic = $this->radius_img($this->pic,$this->radius); list($pic_width, $pic_height) = getimagesize($this->pic); //合成最终图 imagecopyresized($image, $radius_pic, $this->x, $this->y, 0, 0, $this->width, $this->width, $pic_width, $pic_height); imagejpeg($image, $save_path);//保存图,$save_path保存路径 包括对应后缀eg: xxx.jpg //imagepng($image, $save_path);//可保存Png imagedestroy($pic_base );//销毁底图资源 imagedestroy($pic );//销毁合成图资源 } /**圆角处理 返回文件流 */ private function radius_img($imgpath = '', $radius = 20) { header("Content-Type:image/png"); $ext = pathinfo($imgpath); $src_img = null; switch ($ext['extension']) { case 'jpg': $src_img = imagecreatefromjpeg($imgpath); break; case 'jpeg': $src_img = imagecreatefromjpeg($this->pic); break; case 'png': //大坑 为避免PNG-8合成通道消失 png的先转换jpg $src_img_png = imagecreatefrompng($imgpath); $jpg_path = \Yii::$app->runtimePath . '/image/jpg_'.time() . rand(1000, 99999).'.jpg'; imagejpeg($src_img_png,$jpg_path); $src_img = imagecreatefromjpeg($jpg_path); break; } $wh = getimagesize($imgpath); $w = $wh[0]; $h = $wh[1]; // $radius = $radius == 0 ? (min($w, $h) / 2) : $radius; $img = imagecreatetruecolor($w, $h); //这一句一定要有 imagesavealpha($img, true); //拾取一个完全透明的颜色,最后一个参数127为全透明 $bg = imagecolorallocatealpha($img, 255, 255, 255, 127); imagefill($img, 0, 0, $bg); $r = $radius; //圆 角半径 for ($x = 0; $x < $w; $x++) { for ($y = 0; $y < $h; $y++) { $rgbColor = imagecolorat($src_img, $x, $y);//获取像素索引 if (($x >= $radius && $x <= ($w - $radius)) || ($y >= $radius && $y <= ($h - $radius))) { //不在四角的范围内,直接画 imagesetpixel($img, $x, $y, $rgbColor); } else { //在四角的范围内选择画 //上左 $y_x = $r; //圆心X坐标 $y_y = $r; //圆心Y坐标 if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) { imagesetpixel($img, $x, $y, $rgbColor); } //上右 $y_x = $w - $r; //圆心X坐标 $y_y = $r; //圆心Y坐标 if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) { imagesetpixel($img, $x, $y, $rgbColor); } //下左 $y_x = $r; //圆心X坐标 $y_y = $h - $r; //圆心Y坐标 if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) { imagesetpixel($img, $x, $y, $rgbColor); } //下右 $y_x = $w - $r; //圆心X坐标 $y_y = $h - $r; //圆心Y坐标 if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) { imagesetpixel($img, $x, $y, $rgbColor); } } } } unlink($jpg_path);//把临时的文件删了 return $img; }