`

PHP 操作图片水印

    博客分类:
  • PHP
阅读更多

PS:原创文章,如需转载,请注明出处,谢谢!     

本文地址:http://flyer0126.iteye.com/blog/1662162    

 

      之前项目中应用到根据用户情况,及时生成对应个人信息的附带图片,利用到图片水印问题,今天特意封装了一个操作类,特此记录一下,以备今后之需!

/**
 * 水印操作类
 * 
 * 使用说明:
 * 	$wm = new WaterMark();
	$wm->setImSrc('./images/123.jpg'); // 设置背景图
	$wm->setImWater("./images/456.jpg"); // 设置水印图
	$wm->setFont('simhei.ttf', '我就测试一下', 12, '255,0,0'); // 设置水印文字相关(字体库、文本、字体大小、颜色)
	$wm->mark(1, 2, 1, 9); // 设置是否打印图、位置;是否打印字体、位置
 *
 * @author flyer0126
 * @since 2012/08/24
 *
 */
class WaterMark
{
	// 背景图
	private $im_src;          // 背景图文件
	private $im_src_width;    // 背景图宽度
	private $im_src_height;   // 背景图高度
	private $src_im;          // 由背景图创建的新图
	// 水印图
	private $im_water;        // 水印图文件
	private $im_water_width;  // 水印图宽度
	private $im_water_height; // 水印图高度
	private $water_im;        // 由水印图创建的新图
	// 字体
	private $font;            // 字体库
	private $font_text;       // 文本
	private $font_size;       // 字体大小
	private $font_color;      // 字体颜色
	
	/**
	 * 设置背景图
	 * @param $img
	 */
	function setImSrc($img)
	{
		$this->im_src = $img;
		
		//读取背景图片文件
		$srcInfo = @getimagesize($this->im_src);
		$this->im_src_width = $srcInfo[0];
		$this->im_src_height = $srcInfo[1];
		
		//取得背景图片
		$this->src_im = $this->getType($this->im_src, $srcInfo[2]);
	}
	
	/**
	 * 设置水印图
	 * @param $img
	 */
	function setImWater($img)
	{
		$this->im_water = $img;
		
		//读取水印图片文件
		$waterInfo = @getimagesize($this->im_water);
		$this->im_water_width = $waterInfo[0];
		$this->im_water_height = $waterInfo[1];
		
		//取得水印图片
		$this->water_im = $this->getType($this->im_water, $waterInfo[2]);
	}
	
	/**
	 * 设置字体
	 * @param $font
	 */
	function setFont($font, $text, $size, $color)
	{
		$this->font = $font;
		$this->font_text = $text;
		$this->font_size = $size;
		//水印文字颜色('255,255,255')
		$this->font_color = $color;
	}
	
	/**
	 * 根据文件或URL创建一个新图象
	 * @param $img
	 * @param $type
	 * @return resource
	 */
	function getType($img, $type)
	{
		switch($type){
			case 1:$im = imagecreatefromgif($img);break;
			case 2:$im = imagecreatefromjpeg($img);break;
			case 3:$im = imagecreatefrompng($img);break;
			default:break;
		}
		
		return $im;
	}
	
	/**
	 * 根据位置及水印宽高,获取打印的x/y坐标
	 * @param $pos
	 * @param $w
	 * @param $h
	 */
	function getPos($pos, $w, $h)
	{
		switch($pos){
			case 0://随机
				$posX = rand(0, ($this->im_src_width - $w));
				$posY = rand(0, ($this->im_src_height - $h));
				break;
			case 1://1为顶端居左
				$posX = 0;
				$posY = 0;
				break;
			case 2://2为顶端居中
				$posX = ceil($this->im_src_width - $w) / 2;
				$posY = 0;
				break;
			case 3://3为顶端居右
				$posX = $this->im_src_width - $w;
				$posY = 0;
				break;
			case 4://4为中部居左
				$posX = 0;
				$posY = ceil($this->im_src_height - $h) / 2;
				break;
			case 5://5为中部居中
				$posX = ceil($this->im_src_width - $w) / 2;
				$posY = ceil($this->im_src_height - $h) / 2;
				break;
			case 6://6为中部居右
				$posX = $this->im_src_width - $w;
				$posY = ceil($this->im_src_height - $h) / 2;
				break;
			case 7://7为底端居左
				$posX = 0;
				$posY = $this->im_src_height - $h;
				break;
			case 8://8为底端居中
				$posX = ceil($this->im_src_width - $w) / 2;
				$posY = $this->im_src_height - $h;
				break;
			case 9://9为底端居右
				$posX = $this->im_src_width - $w;
				$posY = $this->im_src_height - $h;
				break;
			default://随机
				$posX = rand(0,($this->im_src_width - $w));
				$posY = rand(0,($this->im_src_height - $h));
				break;
		}
		
		return array($posX, $posY);
	}
	
	/**
	 * 校验尺寸
	 * @param $w
	 * @param $h
	 * @return boolean
	 */
	function check_range($w, $h)
	{
		// 校验
		if( ($this->im_src_width < $w) || ($this->im_src_height < $h) ){
			return false;
		}
		
		return true;
	}
	
	/**
	 * 打水印操作
	 * @param $is_image   是1否0水印图片
	 * @param $image_pos  水印图片位置(0~9)
	 * @param $is_text    是1否0水印文字
	 * @param $text_pos   水印文字位置(0~9)
	 * 位置:0-随机位置
	 * 		1为顶端居左,2为顶端居中,3为顶端居右;
	 *      4为中部居左,5为中部居中,6为中部居右;
     *      7为底端居左,8为底端居中,9为底端居右;
	 */
	function mark($is_image=0, $image_pos=0, $is_text=0, $text_pos=0)
	{		
		// 水印图片情况
		if ($is_image)
		{
			$label = '图片的';
			
			if (!$this->check_range($this->im_water_width, $this->im_water_height))
			{
				echo "需要加水印的图片的长度或宽度比水印".$label."还小,无法生成水印!";
				return;
			}
			
			$posArr = $this->getPos($image_pos, $this->im_water_width, $this->im_water_height);
			$posX = $posArr[0];
			$posY = $posArr[1];
			// 拷贝水印到目标文件
			imagecopy($this->src_im, $this->water_im, $posX, $posY, 0, 0, $this->im_water_width, $this->im_water_height);
		}
		// 水印文字情况
		if ($is_text)
		{
			$label = '文字区域';
			//取得此字体的文本的范围
			$temp = imagettfbbox($this->font_size, 0, $this->font, $this->font_text);
			$w = $temp[2] - $temp[0];
			$h = $temp[1] - $temp[7];
			unset($temp);
			
			// 校验
			if (!$this->check_range($w, $h))
			{
				echo "需要加水印的图片的长度或宽度比水印".$label."还小,无法生成水印!";
				return;
			}
			
			$posArr = $this->getPos($text_pos, $w, $h);
			$posX = $posArr[0];
			$posY = $posArr[1];
			// 打印文本
			$red = imagecolorallocate($this->src_im, 255, 0, 0);
			imagettftext($this->src_im, $this->font_size, 0, $posX, $posY, $this->font_color, $this->font, $this->font_text);
		}
		
		// 输出
		$this->show();
		// 清理
		$this->clean();
	}
	
	/**
	 * 输出图像
	 */
	function show()
	{
		header("Content-type: image/png; charset=UTF-8");
		imagepng($this->src_im);
	}
	
	/**
	 * 清理
	 */
	function clean()
	{
		imagedestroy($this->water_im);
		imagedestroy($this->src_im);
	}
	
}

 

PS:最后特意申明一下,使用汉字打印的话,需要注意以下两点:

1、字体库的选择,可以是 simhei.ttf(黑体) , SIMKAI.TTF(楷体) , SIMFANG.TTF(仿宋) ,SIMSUN.TTC(宋体&新宋体) 等 GD 支持的中文字体。

    之前我就是使用simsunb.ttf(简体字),song.TTF(宋体)试了很长时间,发现打印的汉字总是方框,请谨以为戒。

2、 文本编码,需要注意文本编码是否与输出一致,如不一致,请iconv 转换。

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics