2006
06.05

收集的两个PHP增加图片水印的类,Michael还没进行过充分测试,有什么问题请反馈给我。
另外故人居也使用了一个Michael自己开发的增加图片水印函数,有机会一起整理出来给大家。

一、PHP给图片增加水印的类

<?php
Class Gimage{
    
var $src_image_name = "";       //输入图片的文件名(必须包含路径名)
    
var $jpeg_quality = 90;         //jpeg图片质量
    
var $save_image_file = '';      //输出文件名
    
var $wm_image_name = "";        //水印图片的文件名(必须包含路径名)
    
var $wm_image_pos = 1;          //水印图片放置的位置
    
// 0 = middle
    
// 1 = top left
    
// 2 = top right
    
// 3 = bottom right
    
// 4 = bottom left
    
// 5 = top middle
    
// 6 = middle right
    
// 7 = bottom middle
    
// 8 = middle left
    
//other = 3
    
var $wm_image_transition = 20//水印图片与原图片的融合度 (1=100)
    
    
var $wm_text = "";              //水印文字(支持中英文以及带有\r\n的跨行文字)
    
var $wm_text_size = 20;         //水印文字大小
    
var $wm_text_angle = 4;         //水印文字角度,这个值尽量不要更改
    
var $wm_text_pos = 3;           //水印文字放置位置
    
var $wm_text_font = "";         //水印文字的字体
    
var $wm_text_color = "#cccccc"; //水印字体的颜色值
    
    
function create($filename="")
    
{
        
if ($filename) $this->src_image_name = strtolower(trim($filename));
        
        
$src_image_type = $this->get_type($this->src_image_name);
        
$src_image = $this->createImage($src_image_type,$this->src_image_name);
        
if (!$src_image) return;
        
$src_image_w=ImageSX($src_image);
        
$src_image_h=ImageSY($src_image);
        
    
        
if ($this->wm_image_name){
            
$this->wm_image_name = strtolower(trim($this->wm_image_name));
            
$wm_image_type = $this->get_type($this->wm_image_name);
            
$wm_image = $this->createImage($wm_image_type,$this->wm_image_name);
            
$wm_image_w=ImageSX($wm_image);
            
$wm_image_h=ImageSY($wm_image);
            
$temp_wm_image = $this->getPos($src_image_w,$src_image_h,$this->wm_image_pos,$wm_image);
            
$wm_image_x = $temp_wm_image["dest_x"];
            
$wm_image_y = $temp_wm_image["dest_y"];
            
imageCopyMerge($src_image, $wm_image,$wm_image_x,$wm_image_y,0,0,$wm_image_w,$wm_image_h,$this->wm_image_transition);
        
}
    
        
if ($this->wm_text){
            
$this->wm_text = $this->gb2utf8($this->wm_text);
            
$temp_wm_text = $this->getPos($src_image_w,$src_image_h,$this->wm_text_pos);
            
$wm_text_x = $temp_wm_text["dest_x"];
            
$wm_text_y = $temp_wm_text["dest_y"];
            
if(preg_match("/([a-f0-9][a-f0-9])([a-f0-9][a-f0-9])([a-f0-9][a-f0-9])/i", $this->wm_text_color, $color))
            
{
                
$red = hexdec($color[1]);
                
$green = hexdec($color[2]);
                
$blue = hexdec($color[3]);
                
$wm_text_color = imagecolorallocate($src_image, $red,$green,$blue);
            
}else{
                
$wm_text_color = imagecolorallocate($src_image, 255,255,255);
            
}
            
            
imagettftext($src_image, $this->wm_text_size, $this->wm_angle, $wm_text_x, $wm_text_y, $wm_text_color,$this->wm_text_font$this->wm_text);
        
}
    
        
if ($this->save_file) {
            
switch ($this->output_type){
                
case 'gif':$src_img=ImagePNG($src_image, $this->save_file); break;
                
case 'jpeg':$src_img=ImageJPEG($src_image, $this->save_file, $this->jpeg_quality); break;
                
case 'png':$src_img=ImagePNG($src_image, $this->save_file); break;
                
default:$src_img=ImageJPEG($src_image, $this->save_file, $this->jpeg_quality); break;
            
}
        
} else {
            
if ($src_image_type = "jpg") $src_image_type="jpeg";
                
header("Content-type: image/{$src_image_type}");
                
switch ($src_image_type){
                    
case 'gif':$src_img=ImagePNG($src_image); break;
                    
case 'jpg':$src_img=ImageJPEG($src_image, "", $this->jpeg_quality);break;
                    
case 'png':$src_img=ImagePNG($src_image);break;
                    
default:$src_img=ImageJPEG($src_image, "", $this->jpeg_quality);break;
                
}
            
}
        
imagedestroy($src_image);
    
}
    
    
    
/**
     * 根据文件名和类型创建图片
     *
     *
@access private
     *
@param string $type 图片的类型,包括gif,jpg,png
     *
@param string $img_name 图片文件名,包括路径名,如"./mouse.jpg"
     *
@return mixed $tmp_img 返回一图像标识符
     */

    
function createImage($type,$img_name){
            
if (!$type){
                  
$type = $this->get_type($img_name);
            
}
    
              
switch ($type){
                      
case 'gif':
                            
if (function_exists('imagecreatefromgif'))
                                  
$tmp_img=@ImageCreateFromGIF($img_name);
                            
break;
                      
case 'jpg':
                            
$tmp_img=ImageCreateFromJPEG($img_name);
                            
break;
                      
case 'png':
                            
$tmp_img=ImageCreateFromPNG($img_name);
                            
break;
                      
default:
                            
$tmp_img=ImageCreateFromString($img_name);
                            
break;
              
}
              
return $tmp_img;
    
}
    
    
    
/**
     * 根据源图像的长、宽,位置代码,水印图片id来生成把水印放置到源图像中的位置
     *
     *
@access pravate
     *
@param int $sourcefile_width 源图像的宽
     *
@param int $sourcefile_height 原图像的高
     *
@param int $pos  位置代码
     *  0 = middle
     *  1 = top left
     *  2 = top right
     *  3 = bottom right
     *  4 = bottom left
     *  5 = top middle
     *  6 = middle right
     *  7 = bottom middle
     *  8 = middle left
     *
@param int $wm_image 水印图片ID
     *
@return array 返回位置参数数组
     */

    
function getPos($sourcefile_width,$sourcefile_height,$pos,$wm_image=""){
        
if  ($wm_image){
              
$insertfile_width = ImageSx($wm_image);
              
$insertfile_height = ImageSy($wm_image);
        
}else {
              
$lineCount = explode("\r\n",$this->wm_text);
              
$fontSize = imagettfbbox($this->wm_text_size,$this->wm_text_angle,$this->wm_text_font,$this->wm_text);
              
$insertfile_width = $fontSize[2] - $fontSize[0];
              
$insertfile_height = count($lineCount)*($fontSize[1] - $fontSize[3]);
        
}
    
        
switch ($pos){
            
case 0:
              
$dest_x = ( $sourcefile_width / 2 ) - ( $insertfile_width / 2 );
              
$dest_y = ( $sourcefile_height / 2 ) - ( $insertfile_height / 2 );
              
break;
    
            
case 1:
              
$dest_x = 0;
              
if ($this->wm_text){
                  
$dest_y = $insertfile_height;
              
}else{
                  
$dest_y = 0;
              
}
              
break;
    
            
case 2:
                
$dest_x = $sourcefile_width - $insertfile_width;
                
if ($this->wm_text){
                    
$dest_y = $insertfile_height;
                
}else{
                    
$dest_y = 0;
                
}
                
break;
    
            
case 3:
                
$dest_x = $sourcefile_width - $insertfile_width;
                
$dest_y = $sourcefile_height - $insertfile_height;
                
break;
    
            
case 4:
                
$dest_x = 0;
                
$dest_y = $sourcefile_height - $insertfile_height;
                
break;
    
            
case 5:
                
$dest_x = ( ( $sourcefile_width - $insertfile_width ) / 2 );
                
if ($this->wm_text){
                    
$dest_y = $insertfile_height;
                
}else{
                    
$dest_y = 0;
                
}
                
break;
    
            
case 6:
                
$dest_x = $sourcefile_width - $insertfile_width;
                
$dest_y = ( $sourcefile_height / 2 ) - ( $insertfile_height / 2 );
                
break;
    
            
case 7:
                
$dest_x = ( ( $sourcefile_width - $insertfile_width ) / 2 );
                
$dest_y = $sourcefile_height - $insertfile_height;
                
break;
    
            
case 8:
                
$dest_x = 0;
                
$dest_y = ( $sourcefile_height / 2 ) - ( $insertfile_height / 2 );
                
break;
    
            
default:
                
$dest_x = $sourcefile_width - $insertfile_width;
                
$dest_y = $sourcefile_height - $insertfile_height;
                
break;
        
}
        
return array("dest_x"=>$dest_x,"dest_y"=>$dest_y);
    
}
    
    
/**
     * 指定的文字转换为UTF-8格式,包括中英文混合
     *
     *
@access private
     *
@param string $gb 输入gb类型的字数串
     *
@return string $utf8
     */

    
function gb2utf8($gb)
    
{
        
if(!trim($gb))
            
return $gb;
        
$filename="./gb2312.txt";
        
$tmp=file($filename);
        
$codetable=array();
        
while(list($key,$value)=each($tmp))
        
$codetable[hexdec(substr($value,0,6))]=substr($value,7,6);
        
        
$utf8="";
        
while($gb)
        
{
            
if (ord(substr($gb,0,1))>127) {
                
$tthis=substr($gb,0,2);
                
$gb=substr($gb,2,strlen($gb)-2);
                
$utf8.=$this->u2utf8(hexdec($codetable[hexdec(bin2hex($tthis))-0x8080]));
            
} else {
                
$tthis=substr($gb,0,1);
                
$gb=substr($gb,1,strlen($gb)-1);
                
$utf8.=$this->u2utf8($tthis);
            
}
        
}
        
return $utf8;
    
}
    
    
function u2utf8($c)
    
{
        
$str="";
        
if ($c < 0x80) {
            
$str.=$c;
        
} else if ($c < 0x800) {
            
$str.=chr(0xC0 | $c>>6);
            
$str.=chr(0x80 | $c & 0x3F);
        
} else if ($c < 0x10000) {
            
$str.=chr(0xE0 | $c>>12);
            
$str.=chr(0x80 | $c>>6 & 0x3F);
            
$str.=chr(0x80 | $c & 0x3F);
        
} else if ($c < 0x200000) {
            
$str.=chr(0xF0 | $c>>18);
            
$str.=chr(0x80 | $c>>12 & 0x3F);
            
$str.=chr(0x80 | $c>>6 & 0x3F);
            
$str.=chr(0x80 | $c & 0x3F);
        
}
        
return $str;
    
}
    
    
/**
     * 获得图片的格式,包括jpg,png,gif
     *
     *
@access private
     *
@param string $img_name 图片文件名,可以包括路径名
     *
@return string $type
     */

    
function get_type($img_name)
    
{
        
$name_array = explode(".",$img_name);
        
if (preg_match("/\.(jpg|jpeg|gif|png)$/", $img_name, $matches))
            
$type = strtolower($matches[1]);
        
else
            
$type = "string";
        
        
return $type;
    
}
 
}
?>

该类使用方法如下:

$img = new Gimage();
$img->wm_text = "www.discuz.com";
$img->wm_text_font = "./STXINWEI.TTF";
$img->create("./mouse.jpg");

mouse.jpg 是你要在其上添加水印的图片名称,注意包含路径名
STXINWEI.TTF 是字体文件的路径名+文件名
这就是一个简单的测试。如果要调整更复杂的显示效果,只要修改一下类中的属性就可以了,例如把字体放大就可以
$img->wm_text_size = 20;
增加水印图片就可以
$img->wm_image_name=”文件名”;

二、给图片增加水印的php文件,包含实际运行代码,支持图片和文字水印

<?php
/*
* 功能:PHP图片水印 (水印支持图片或文字)
* 参数:
*      $groundImage    背景图片,即需要加水印的图片,暂只支持GIF,JPG,PNG格式;
*      $waterPos       水印位置,有10种状态,0为随机位置;
*                      1为顶端居左,2为顶端居中,3为顶端居右;
*                      4为中部居左,5为中部居中,6为中部居右;
*                      7为底端居左,8为底端居中,9为底端居右;
*      $waterImage     图片水印,即作为水印的图片,暂只支持GIF,JPG,PNG格式;
*      $waterText      文字水印,即把文字作为为水印,支持ASCII码,不支持中文;
*      $textFont       文字大小,值为1、2、3、4或5,默认为5;
*      $textColor      文字颜色,值为十六进制颜色值,默认为#FF0000(红色);
*
* 注意:Support GD 2.0,Support FreeType、GIF Read、GIF Create、JPG 、PNG
*      $waterImage 和 $waterText 最好不要同时使用,选其中之一即可,优先使用 $waterImage。
*      当$waterImage有效时,参数$waterString、$stringFont、$stringColor均不生效。
*      加水印后的图片的文件名和 $groundImage 一样。
* 作者:longware @ 2004-11-3 14:15:13
*/

function imageWaterMark($groundImage,$waterPos=0,$waterImage="",$waterText="", $textFont=5,$textColor="#FF0000")
{
    
$isWaterImage = FALSE;
    
$formatMsg = "暂不支持该文件格式,请用图片处理软件将图片转换为GIF、JPG、PNG格式。";
 
    
//读取水印文件
    
if(!empty($waterImage) && file_exists($waterImage)) {
        
$isWaterImage = TRUE;
        
$water_info = getimagesize($waterImage);
        
$water_w    = $water_info[0];//取得水印图片的宽
        
$water_h    = $water_info[1];//取得水印图片的高
 
        
switch($water_info[2])  {   //取得水印图片的格式 
            
case 1:$water_im = imagecreatefromgif($waterImage);break;
            
case 2:$water_im = imagecreatefromjpeg($waterImage);break;
            
case 3:$water_im = imagecreatefrompng($waterImage);break;
            
default:die($formatMsg);
        
}
    
}
 
    
//读取背景图片
    
if(!empty($groundImage) && file_exists($groundImage)) {
        
$ground_info = getimagesize($groundImage);
        
$ground_w    = $ground_info[0];//取得背景图片的宽
        
$ground_h    = $ground_info[1];//取得背景图片的高
 
        
switch($ground_info[2]) {   //取得背景图片的格式 
            
case 1:$ground_im = imagecreatefromgif($groundImage);break;
            
case 2:$ground_im = imagecreatefromjpeg($groundImage);break;
            
case 3:$ground_im = imagecreatefrompng($groundImage);break;
            
default:die($formatMsg);
        
}
    
} else {
        
die("需要加水印的图片不存在!");
    
}
 
    
//水印位置
    
if($isWaterImage) { //图片水印 
        
$w = $water_w;
        
$h = $water_h;
        
$label = "图片的";
    
} else {  //文字水印
        
$temp = imagettfbbox(ceil($textFont*2.5),0,"./cour.ttf",$waterText);//取得使用 TrueType 字体的文本的范围
        
$w = $temp[2] - $temp[6];
        
$h = $temp[3] - $temp[7];
        
unset($temp);
        
$label = "文字区域";
    
}
    
if( ($ground_w<$w) || ($ground_h<$h) ) {
        
echo "需要加水印的图片的长度或宽度比水印".$label."还小,无法生成水印!";
        
return;
    
}
    
switch($waterPos) {
        
case 0://随机
            
$posX = rand(0,($ground_w - $w));
            
$posY = rand(0,($ground_h - $h));
            
break;
        
case 1://1为顶端居左
            
$posX = 0;
            
$posY = 0;
            
break;
        
case 2://2为顶端居中
            
$posX = ($ground_w - $w) / 2;
            
$posY = 0;
            
break;
        
case 3://3为顶端居右
            
$posX = $ground_w - $w;
            
$posY = 0;
            
break;
        
case 4://4为中部居左
            
$posX = 0;
            
$posY = ($ground_h - $h) / 2;
            
break;
        
case 5://5为中部居中
            
$posX = ($ground_w - $w) / 2;
            
$posY = ($ground_h - $h) / 2;
            
break;
        
case 6://6为中部居右
            
$posX = $ground_w - $w;
            
$posY = ($ground_h - $h) / 2;
            
break;
        
case 7://7为底端居左
            
$posX = 0;
            
$posY = $ground_h - $h;
            
break;
        
case 8://8为底端居中
            
$posX = ($ground_w - $w) / 2;
            
$posY = $ground_h - $h;
            
break;
        
case 9://9为底端居右
            
$posX = $ground_w - $w;
            
$posY = $ground_h - $h;
            
break;
        
default://随机
            
$posX = rand(0,($ground_w - $w));
            
$posY = rand(0,($ground_h - $h));
            
break;     
    
}
 
    
//设定图像的混色模式
    
imagealphablending($ground_im, true);
 
    
if($isWaterImage) { //图片水印
        
imagecopy($ground_im, $water_im, $posX, $posY, 0, 0, $water_w,$water_h);//拷贝水印到目标文件         
    
} else {//文字水印
        
if( !empty($textColor) && (strlen($textColor)==7) ) {
            
$R = hexdec(substr($textColor,1,2));
            
$G = hexdec(substr($textColor,3,2));
            
$B = hexdec(substr($textColor,5));
        
} else {
            
die("水印文字颜色格式不正确!");
        
}
        
imagestring ( $ground_im, $textFont, $posX, $posY, $waterText, imagecolorallocate($ground_im, $R, $G, $B));         
    
}
 
    
//生成水印后的图片
    @
unlink($groundImage);
    
switch($ground_info[2]) {//取得背景图片的格式
        
case 1:imagegif($ground_im,$groundImage);break;
        
case 2:imagejpeg($ground_im,$groundImage);break;
        
case 3:imagepng($ground_im,$groundImage);break;
        
default:die($errorMsg);
    
}
 
    
//释放内存
    
if(isset($water_info)) unset($water_info);
    
if(isset($water_im)) imagedestroy($water_im);
    
unset($ground_info);
    
imagedestroy($ground_im);
}
 
 
 
if(isset($_FILES) && !empty($_FILES['userfile']) && $_FILES['userfile']['size']>0) {
    
$uploadfile = "./".time()."_".$_FILES['userfile']['name'];
    
if (copy($_FILES['userfile']['tmp_name'], $uploadfile)) {
        
echo "OK<br>";
 
        
//文字水印
        
imageWaterMark($uploadfile,0,"","HTTP://BLOG.CSDN.NET/LONGWARE/",5,"#FF0000");
 
        
//图片水印
        
//$waterImage="./Hanweb_shuiyin.gif";//水印图片路径
        
//imageWaterMark($uploadfile,0,$waterImage);
 
        
echo "<img src=\"".$uploadfile."\" border=\"0\">";
    
} else {
        
echo "Fail<br>";
    
}
}
?>
 
<form enctype="multipart/form-data" method="POST">
文件: <input name="userfile" type="file">
<input type="submit" value="上传">
</form>

有什么问题欢迎大家一起探讨,如果有更好的实现思路欢迎分享。

No Comment.

Add Your Comment

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word