获取带参数的微信小程序二维码-以及修改二维码LOGO源码分享

具体使用到的方法,建议先看代码再从目录中找相应的方法

    • 获取二维码方法:
    • Applet()类:
    • http请求方法:
    • 剪切上传的logo图片为圆形方法:
    • 在二维码中间区域镶嵌图片方法:

逻辑分析:
1.首先准备小程序的APPID和SECRET,可在微信公众号中获取。以及准备好想要带进二维码里边的参数
2.logo上传:接受到上传的logo图片,先把图片画成圆形,然后获取到二维码后,把logo图片镶嵌到二维码上。

具体看代码演示:用到的重要方法看目录

获取二维码方法:

public function recreateOp(){
		if (request()->ispost() && request()->isAjax()) {
            $logo = request()->file('file'); // 上传的logo
			$width = input('width'); // 宽度
			$shape = input('shape'); // 二维码形状
			if($width < 280 || $width > 1280){
				return json_encode(['status'=>ERROR,'msg'=>'宽度有误']);
			}
			if($shape != 1 && $shape != 2){
				return json_encode(['status' => ERROR, 'msg' => '类型有误']);
			}

			$appid = "你自己的appid在微信公众号中查找";
			$appsecret = "你的appsecret在微信公众号中查找";
			$usertoken = "你需要带进二维码中的参数";
			if (!$usertoken) {
				return json_encode(['status' => ERROR, 'msg' => '信息有误']);
			}
            $Applet = new Applet(); // Applet() 类
            if (!empty($logo)) {
                $filename = uniqid('qrlogo_img_' . false);
                $retImg = upload_files($logo, USER_QRLOGO_PATH, $filename); // 文件上传
                if ($retImg['status'] == 9) {
                    $head_img = USER_QRLOGO_PATH.$retImg['msg'];
                } else {
                    return json_encode(['status' => 'error', 'msg' => $retImg['msg']]);
                }
                $logo = $Applet->yuanImg($head_img); // 把上传的logo使用PHP自带的GD库画成圆形
                @unlink($head_img); // 删除上传的logo图片
            }

            $Applet->creatCode($appid, $appsecret, $usertoken, $this->userinfo['uid'], $shape, $width,$logo);
			return json_encode(['status' => SUCCESS, 'msg' => '二维码已重新生成','url'=>url('jieru')]);
		}
	}

Applet()类:

/* 
	* 生成小程序接入专属二维码
	* $appid	小程序appid
	* $appsecret	小程序appsecret
	* $usertoken	通行码
	* $shape	二维码形状:1-菊花型,2-方形
	* $width	二维码宽度
	*/ 
	public function creatCode($appid, $appsecret, $usertoken, $uid, $shape = 1, $width=280,$logo = '') {
		//获取access_token
		$access_token = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret";
		$json = $this->httpRequest($access_token);
		$token = json_decode($json, true);
		$token = $token['access_token'];
		// 构建请求二维码参数
		switch ($shape) {
			case 1:	//菊花型
				$qcode = "https://api.weixin.qq.com/wxa/getwxacode?access_token=$token"; //菊花二维码
				break;
			
			default:	//方型
				$qcode = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=$token"; // 方形二维码
				break;
		}
		// 把需要带二维码中的参数组合发送给微信接口
		$param = json_encode(array("path" => "pages/login/login?tongxingma=$usertoken", "width" => $width));
		// $res 是获取到的二维码,可以将二维码存到数据库中
		$res = $this->httpRequest($qcode, $param, "POST"); // 发送http请求换取带参数的二维码
        if (!empty($logo)) {
            $res = $this->qrcodeWithLogo($res,$logo,$shape); // 在二维码的中间区域镶嵌图片
        }

		//保存二维码图片
		$file_name = time(). createStr(6) . ".png"; // 生成二维码图片名称
		$path = ROOT_PATH . 'public/uploads/appLetCode/'. $usertoken.'/'; // 保存路径
		$upload = $path . $file_name;
		if (!file_exists($path)) mkdir($path, 0777, true); 
		file_put_contents($upload, $res);
		//保存数据到数据库
		$olddata = model('Applet')->where(['uid' => $uid])->field('numid,name')->find();
		if(!$olddata){	//新增数据
			$data = [
				'uid' => $uid,
				'name' => $file_name,
				'width' => $width,
				'shape' => $shape,
				'addtime' => time(),
				'status' => 9,
			];
			model('Applet')->allowField(true)->save($data);
		}else{	//更新数据
			if (file_exists($path . $olddata['name'])) {
				@unlink($path . $olddata['name']);
			}
			$data = [
				'numid' => $olddata['numid'],
				'name' => $file_name,
				'width' => $width,
				'shape' => $shape,
				'addtime' => time(),
				'status' => 9,
			];
			model('Applet')->allowField(true)->isUpdate(true)->save($data);
		}
		return [
			//转成base64
			'base64_image' =>  	"data:image/jpeg;base64," . base64_encode($res), 
			'upload'       => 	$file_name,
		];
	}

http请求方法:

//把请求发送到微信服务器换取二维码
	private function httpRequest($url, $data = '', $method = 'GET'){
		$curl = curl_init();
		curl_setopt($curl, CURLOPT_URL, $url);
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
		curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
		curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
		curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
		if ($method == 'POST') {
			curl_setopt($curl, CURLOPT_POST, 1);
			if ($data != '') {
				curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
			}
		}

		curl_setopt($curl, CURLOPT_TIMEOUT, 30);
		curl_setopt($curl, CURLOPT_HEADER, 0);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		$result = curl_exec($curl);
		curl_close($curl);
		return $result;
	}

剪切上传的logo图片为圆形方法:

  /**
     * 剪切图片为圆形
     * @param  $picture 图片数据流 比如file_get_contents(imageurl)返回的东东
     * @return 图片数据流
     */
    public function yuanImg($picture) {
        $picture = file_get_contents($picture);
        $src_img = imagecreatefromstring($picture);
        $w = imagesx($src_img);
        $h = imagesy($src_img);
        $w = min($w, $h);
        $h = $w;
        $img = imagecreatetruecolor($w, $h);
        //这一句一定要有
        imagesavealpha($img, true);
        //拾取一个完全透明的颜色,最后一个参数127为全透明
        $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
        imagefill($img, 0, 0, $bg);
        $r = $w / 2; //圆半径
        $y_x = $r; //圆心X坐标
        $y_y = $r; //圆心Y坐标
        for ($x = 0; $x < $w; $x++) {
            for ($y = 0; $y < $h; $y++) {
                $rgbColor = imagecolorat($src_img, $x, $y);
                if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
            }
        }
        /**
         * 如果想要直接输出图片,应该先设header。header("Content-Type: image/png; charset=utf-8");
         * 并且去掉缓存区函数
         */
        //获取输出缓存,否则imagepng会把图片输出到浏览器
        ob_start();
        imagepng($img);
        imagedestroy($img);
        $contents = ob_get_contents();
        ob_end_clean();
        return $contents;
    }

在二维码中间区域镶嵌图片方法:

  /**
     * 在二维码的中间区域镶嵌图片
     * @param $QR 二维码数据流。比如file_get_contents(imageurl)返回的东东,或者微信给返回的东东
     * @param $logo 中间显示图片的数据流。比如file_get_contents(imageurl)返回的东东
     * @return  返回图片数据流
     */
    public function qrcodeWithLogo($QR, $logo,$shape) {
        $QR = imagecreatefromstring($QR);
        $logo = imagecreatefromstring($logo);
        $QR_width = imagesx($QR);//二维码图片宽度
        $QR_height = imagesy($QR);//二维码图片高度
        $logo_width = imagesx($logo);//logo图片宽度
        $logo_height = imagesy($logo);//logo图片高度
        if ($shape == 1 ) {
            $logo_qr_width = $QR_width / 2.2;//组合之后logo的宽度(占二维码的1/2.2)
        } else {
            $logo_qr_width = $QR_width / 4;//组合之后logo的宽度(占二维码的1/4)
        }
        $scale = $logo_width / $logo_qr_width;//logo的宽度缩放比(本身宽度/组合后的宽度)
        $logo_qr_height = $logo_height / $scale;//组合之后logo的高度
        $from_width = ($QR_width - $logo_qr_width) / 2;//组合之后logo左上角所在坐标点
        /**
         * 重新组合图片并调整大小
         * imagecopyresampled() 将一幅图像(源图象)中的一块正方形区域拷贝到另一个图像中
         */
        imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);
        /**
         * 如果想要直接输出图片,应该先设header。header("Content-Type: image/png; charset=utf-8");
         * 并且去掉缓存区函数
         */
        //获取输出缓存,否则imagepng会把图片输出到浏览器
        ob_start();
        imagepng($QR);
        imagedestroy($QR);
        imagedestroy($logo);
        $contents = ob_get_contents();
        ob_end_clean();
        return $contents;
    }

  

你可能感兴趣的:(PHP)