php制作圆形用户头像,思路+自定义封装类源代码

2 篇文章 0 订阅
1 篇文章 0 订阅

思路

使用图层的方法设计,共需要创建3个图像层

1.底层:最后生成的图像

2.真实用户头像:作为中间层,用户上传的真实头像图片

3.圆形蒙版:作为最上层,在蒙版中绘制圆形,并设置为透明


这种设计有缺点,即蒙版的背景填充色必须和网页中需要显示的周边颜色相同,上图:

    


是否有更好的解决方法?(除了用c扩展)



上代码

主功能类 avatar.class.php

class avatar
{
	private $fileName; //文件的绝对路径(或基于最终调用文件的相对路径)
	private $rgb; //颜色索引(数组 array(255,255,0) 或 16进制值 ffff00/#ffff00/ff0/#ff0)
	private $size; //图像大小
	private $imgInfo; //图像信息
	
	/**
	 * 初始化
	 * Enter description here ...
	 * @param string $fileName 文件的绝对路径(或基于最终调用文件的相对路径)
	 * @param mixed $rgb 颜色索引(数组 array(255,255,0) 或 16进制值 ffff00/#ffff00/ff0/#ff0)
	 * @param int $size 图像大小
	 */
	public function __construct($fileName, $rgb, $size)
	{
		$this->fileName = $fileName;
		
		if(is_array($rgb)){
			$this->rgb = $rgb; //rgb颜色数组 array(255,255,0)
		}else{
			//有的人喜欢带#号
			$rgb = trim($rgb, '#');
			//处理缩写形式
			if (strlen($rgb)==3){
				$_tmp = $rgb[0].$rgb[0].$rgb[1].$rgb[1].$rgb[2].$rgb[2];
				$rgb = $_tmp;
			}
			$this->rgb = $this->createRGB($rgb); //16进制值 ffff00
		}
		
		$this->size = $size;
		
		$this->imgInfo = getimagesize($this->fileName);
		
		if(!$this->imgInfo){
			throw Exception("无法读取图像文件");
		}
		if(!in_array($this->imgInfo[2], array(2,3))){
			//仅允许jpg和png
			throw Exception("图像格式不支持");
		}
	}
	
	/**
	 * 显示图像
	 * Enter description here ...
	 */
	public function show()
	{
		header("content-type:image/png");
		
		$shadow = $this->createshadow(); //遮罩图片
		
		//创建一个方形图片
		$imgbk = imagecreatetruecolor($this->size, $this->size); //目标图片
		
		switch ($this->imgInfo[2]){
			case 2:
				$imgfk = imagecreatefromjpeg($this->fileName); //原素材图片
				break;
			case 3:
				$imgfk = imagecreatefrompng($this->fileName); //原素材图片
			default:
				return ;
				break;
		}
		
		
		$realSize = $this->imgInfo[0]<$this->imgInfo[1]? $this->imgInfo[0] : $this->imgInfo[1];
		
		imagecopyresized($imgbk, $imgfk, 0, 0, 0, 0, $this->size, $this->size, $realSize, $realSize);
		imagecopymerge($imgbk, $shadow, 0, 0, 0, 0, $this->size, $this->size, 100);
		
		//创建图像
		imagepng($imgbk);
		
		//销毁资源
		imagedestroy($imgbk);
		imagedestroy($imgfk);
		imagedestroy($shadow);
	}
	
	/**
	 * 创建一个圆形遮罩
	 * Enter description here ...
	 * @param array 10进制颜色数组
	 */
	private function createshadow()
	{
		
		$img = imagecreatetruecolor($this->size, $this->size);
		
		imageantialias($img, true); //开启抗锯齿
		
		$color_bg = imagecolorallocate($img, $this->rgb[0], $this->rgb[1], $this->rgb[2]); //背景色
		$color_fg = imagecolorallocate($img, 0, 0, 0); //前景色,主要用来创建圆形
		
		imagefilledrectangle($img, 0, 0, 200, 200, $color_bg);
		imagefilledarc($img, 100, 100, 200, 200, 0, 0, $color_fg, IMG_ARC_PIE);
		
		imagecolortransparent($img, $color_fg); //将前景色转换为透明
		
		
		return $img;
	}
	
	/**
	 * 将字符形式16进制串转为10进制
	 * Enter description here ...
	 * @param $str
	 */
	private function getIntFromHexStr($str)
	{
		$format = '0123456789abcdef';
		
		$sum = 0;
		
		for($i=strlen($str)-1, $c=0, $j=0; $i>=$c; $i--,$j++){
			$index = strpos($format, $str[$i]);//strpos从0计算
			$sum+=$index * pow(16,$j);
		}
		
		return $sum;
	}
	
	/**
	 * 将16进制颜色转为10进制颜色值数组(RGB)
	 * Enter description here ...
	 * @param $str 16进制串(如:ff9900)
	 */
	private function createRGB($str)
	{
		$rgb = array();
		if(strlen($str) != 6){
			$rgb[] = 0xff;
			$rgb[] = 0xff;
			$rgb[] = 0xff;
			return $rgb; //默认白色
		}
	
		$rgb[] = $this->getIntFromHexStr(substr($str, 0, 2));
		$rgb[] = $this->getIntFromHexStr(substr($str, 2, 2));
		$rgb[] = $this->getIntFromHexStr(substr($str, 4, 2));
		
		return $rgb;
		
	}
}

测试程序 demo6.php

include "avatar.class.php";

$imgPath = trim($_GET['img']);
$rgbStr = trim($_GET['rgb']);

//$rgbStr = '#dedede';

$img = new avatar($imgPath, $rgbStr, 200);
$img->show();

测试前端页面 ShadowDemo.php

<?php 
$rgb = 'dedede';
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style>
	h1{
		margin:20px;
	}
	ul{
		width:300px;
	}
	ul li{
		list-style-type: none;
		width:100%;
		float:Left;
		margin-top: 20px;
		border-bottom:1px solid #ccc;
	}
	li .img-block{
		float:left;
	}
	li .info-block{
		float:left;
		margin-left:20px;
	}
</style>
</head>
<body style="background-color:#<?php echo $rgb; ?>">
	<h1>user list</h1>
	<ul>
		<li>
			<div class="img-block"><img src="./demo6.php?img=img-demo1.jpg&rgb=<?php echo $rgb; ?>" style="width: 70px" /></div>
			<div class="info-block">
				<p>name: lixin</p>
				<p>say: i`am shadow!</p>
			</div>			
		</li>
		<li>
			<div class="img-block"><img src="./demo6.php?img=img-demo2.jpg&rgb=<?php echo $rgb; ?>" style="width: 70px" /></div>
			<div class="info-block">
				<p>name: lucy</p>
				<p>say: i`am sun!</p>
			</div>			
		</li>
		<li>
			<div class="img-block"><img src="./demo6.php?img=img-demo3.jpg&rgb=<?php echo $rgb; ?>" style="width: 70px" /></div>
			<div class="info-block">
				<p>name: liu cou</p>
				<p>say: i`am wind!</p>
			</div>			
		</li>
	</ul>

<!-- 
	<img src="./demo5.php?img=img-demo1.jpg" style="width: 70px" />
	<img src="./demo5.php?img=img-demo2.jpg" style="width: 70px" />
	<img src="./demo5.php?img=img-demo3.jpg" style="width: 70px" />
	 -->
</body>
</html>






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值