1. 程式人生 > 實用技巧 >php Gd庫處理合成圖片 生成圓角圖

php Gd庫處理合成圖片 生成圓角圖

png分為png-8、png-24‘、png-32

合成png-8顏色通道消失問題可將png轉換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;

    }