php实现给一张图片加上水印效果


Posted in PHP onJanuary 02, 2016

php实现给一张图片加上水印效果

<?php
/**
 * 功能:给一张图片加上水印效果
 *      $i 要加水印效果的图片
 *      $t 水印文字
 *      $size 文字大小
 *      $pos 水印的位置
 *      $color 文字的颜色
 *      $flag 是布尔值,主要用来区分是不是原图上加水印
 *      $type 如果$flag等于false 则新图上加上水印 新文件名为 原名_txt.jpg
 */
function txt($i,$t='版权所有',$size=25,$pos=5,$color='rand',$flag=true,$type='_txt'){
  $img = imagecreatefromjpeg($i);
  $w = imagesx($img);
  $h = imagesy($img);
  $font = dirname(__FILE__).'/font/ls.ttf';
  $ps = imagettfbbox($size,0,$font,$t);
  $tw = $ps[4];
  $th = abs($ps[5]);
  switch($pos){
    case 1:break;  
    case 2:break;  
    case 3:break;  
    case 4:break;  
    case 5:$x=($w-$tw)/2;$y=($h-$th)/2+$th;break;  
    case 6:break;  
    case 7:break;  
    case 8:break;  
    case 9:break;  
    default:break;
  }
  $c = getcolor($img,$color);
  imagettftext($img,$size,0,$x,$y,$c,$font,$t);
  if($flag){
    imagejpeg($img,$i); 
  }else{
    $ext = ext($i);
    $ppp = rtrim($i,'.'.$ext);
    $ppp = $ppp.$type.'.'.$ext;
    imagejpeg($img,$ppp);
  }
}
 
function getcolor($i,$c='rand',$a=50){
  $cc = '';
  switch($c){
    case 'white':$cc=imagecolorallocatealpha($i,255,255,255,$a);break;
    case 'black':$cc=imagecolorallocatealpha($i,0,0,0,$a);break;
    case 'red':$cc=imagecolorallocatealpha($i,255,0,0,$a);break;
    case 'green':$cc=imagecolorallocatealpha($i,0,255,0,$a);break;
    case 'blue':$cc=imagecolorallocatealpha($i,0,0,255,$a);break;
    case 'orange':$cc=imagecolorallocatealpha($i,0xff,0x66,0x33,$a);break;
    case 'yellow':$cc=imagecolorallocatealpha($i,255,255,0,$a);break;
    case 'rand':$cc=imagecolorallocatealpha($i,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255),$a);break;
    default:
      $cs = substr($c,1);
      $ok = str_split($cs,2);
      $cc = imagecolorallocatealpha($i,hexdec($ok[0]),hexdec($ok[1]),hexdec($ok[2]),$a);
    break;   
  }
  return $cc;
}
 
 
/**
 * 功能是:返回扩展名
 */
 
function ext($f){
  $exts = explode('.',$f);
  return end($exts);
}
 
/**
 * 功能是:返回文件名,不含扩展名
 */
function name($f){
  $s = explode('/',$f);
  $fn = end($s);
  return rtrim($fn,'.'.ext($f));
}

我们再来看一个支持以图片和文字两种方式给图片添加水印。图片支持GIF,PNG,JPG三种格式,水印图片支持PNG和GIF

function setWater($imgSrc,$markImg,$markText,$TextColor,$markPos,$fontType,$markType)
{

  $srcInfo = @getimagesize($imgSrc);
  $srcImg_w  = $srcInfo[0];
  $srcImg_h  = $srcInfo[1];
    
  switch ($srcInfo[2]) 
  { 
    case 1: 
      $srcim =imagecreatefromgif($imgSrc); 
      break; 
    case 2: 
      $srcim =imagecreatefromjpeg($imgSrc); 
      break; 
    case 3: 
      $srcim =imagecreatefrompng($imgSrc); 
      break; 
    default: 
      die("不支持的图片文件类型"); 
      exit; 
  }
    
  if(!strcmp($markType,"img"))
  {
    if(!file_exists($markImg) || empty($markImg))
    {
      return;
    }
      
    $markImgInfo = @getimagesize($markImg);
    $markImg_w  = $markImgInfo[0];
    $markImg_h  = $markImgInfo[1];
      
    if($srcImg_w < $markImg_w || $srcImg_h < $markImg_h)
    {
      return;
    }
      
    switch ($markImgInfo[2]) 
    { 
      case 1: 
        $markim =imagecreatefromgif($markImg); 
        break; 
      case 2: 
        $markim =imagecreatefromjpeg($markImg); 
        break; 
      case 3: 
        $markim =imagecreatefrompng($markImg); 
        break; 
      default: 
        die("不支持的水印图片文件类型"); 
        exit; 
    }
      
    $logow = $markImg_w;
    $logoh = $markImg_h;
  }
    
  if(!strcmp($markType,"text"))
  {
    $fontSize = 16;
    if(!empty($markText))
    {
      if(!file_exists($fontType))
      {
        return;
      }
    }
    else {
      return;
    }
      
    $box = @imagettfbbox($fontSize, 0, $fontType,$markText);
    $logow = max($box[2], $box[4]) - min($box[0], $box[6]);
    $logoh = max($box[1], $box[3]) - min($box[5], $box[7]);
  }
    
  if($markPos == 0)
  {
    $markPos = rand(1, 9);
  }
    
  switch($markPos)
  {
    case 1:
      $x = +5;
      $y = +5;
      break;
    case 2:
      $x = ($srcImg_w - $logow) / 2;
      $y = +5;
      break;
    case 3:
      $x = $srcImg_w - $logow - 5;
      $y = +15;
      break;
    case 4:
      $x = +5;
      $y = ($srcImg_h - $logoh) / 2;
      break;
    case 5:
      $x = ($srcImg_w - $logow) / 2;
      $y = ($srcImg_h - $logoh) / 2;
      break;
    case 6:
      $x = $srcImg_w - $logow - 5;
      $y = ($srcImg_h - $logoh) / 2;
      break;
    case 7:
      $x = +5;
      $y = $srcImg_h - $logoh - 5;
      break;
    case 8:
      $x = ($srcImg_w - $logow) / 2;
      $y = $srcImg_h - $logoh - 5;
      break;
    case 9:
      $x = $srcImg_w - $logow - 5;
      $y = $srcImg_h - $logoh -5;
      break;
    default: 
      die("此位置不支持"); 
      exit;
  }
    
  $dst_img = @imagecreatetruecolor($srcImg_w, $srcImg_h);
    
  imagecopy ( $dst_img, $srcim, 0, 0, 0, 0, $srcImg_w, $srcImg_h);
    
  if(!strcmp($markType,"img"))
  {
    imagecopy($dst_img, $markim, $x, $y, 0, 0, $logow, $logoh);
    imagedestroy($markim);
  }
    
  if(!strcmp($markType,"text"))
  {
    $rgb = explode(',', $TextColor);
      
    $color = imagecolorallocate($dst_img, $rgb[0], $rgb[1], $rgb[2]);
    imagettftext($dst_img, $fontSize, 0, $x, $y, $color, $fontType,$markText);
  }
    
  switch ($srcInfo[2]) 
  { 
    case 1:
      imagegif($dst_img, $imgSrc); 
      break; 
    case 2: 
      imagejpeg($dst_img, $imgSrc); 
      break; 
    case 3: 
      imagepng($dst_img, $imgSrc); 
      break;
    default: 
      die("不支持的水印图片文件类型"); 
      exit; 
  }
    
  imagedestroy($dst_img);
  imagedestroy($srcim);
}

参数说明:

$imgSrc:目标图片,可带相对目录地址,
$markImg:水印图片,可带相对目录地址,支持PNG和GIF两种格式,如水印图片在执行文件mark目录下,可写成:mark/mark.gif
$markText:给图片添加的水印文字
$TextColor:水印文字的字体颜色
$markPos:图片水印添加的位置,取值范围:0~9
0:随机位置,在1~8之间随机选取一个位置
1:顶部居左 2:顶部居中 3:顶部居右 4:左边居中
5:图片中心 6:右边居中 7:底部居左 8:底部居中 9:底部居右
$fontType:具体的字体库,可带相对目录地址
$markType:图片添加水印的方式,img代表以图片方式,text代表以文字方式添加水印

代码注释:

第4~6行:获取目标图片的宽度和高度
第8~22行:根据图片类型调用不同的函数,获得操作图像标识符

GetImageSize函数知识点:GetImageSize不需要安装 GD度就可使用,其返回值数组有四个元素。索引值0是图片高度。索引值1是图片的宽度。索引值2是图片的文件格式,其值1为GIF格式、2为JPEG/JPG格式、3为PNG格式。索引值3为图片的高与宽字符串,height=xxx width=yyy。返回的图片宽度和高度单位都是像素(pixel)

第24~58行:当选择图片方式给目标图片添加水印时,获取水印图片的宽度和高度,通常情况都是网站的logo。如果目标图片比水印图片宽度或者高度小或者水印图片不存在,则跳出这个函数。

return语句知识点:直接return 表示什么都不返回,直接结束这个函数。也可以理解成返回 NULL。

第60~77行:当选择文字方式给目标图片添加水印时,首先设定水印文字的大小,默认我设置为16px,你可以根据需要自行调整字体大小。如果字体文件不存在,跳出函数,最后通过imagettfbbox函数获得此设定格式的文字的虚拟长宽。

imagettfbbox函数知识点:此函数返回一个含有8个单元的数组表示文本外框的四个角,索引值含义:0代表左下角 X 位置,1代表坐下角 Y 位置,2代表右下角 X 位置,3代表右下角 Y 位置,4代表右上角 X 位置,5代表右上角 Y 位置,6代表左上角 X 位置,7代表左上角 Y 位置。此函数同时需要GD 库和FreeType库的支持
max函数返回参数中数值最大的值。

第79~125行:根据设定的图片水印位置计算具体坐标值,你可以根据效果具体细化水印的位置。

第127~129行:新建一个和目标图片大小一致的图片。

注:由于imagecreatetruecolor函数范围的是一个黑色图片,所以如果你的目标图片是透明的,则生成的新图将不会是透明色。

第131~162行:根据图片或者文字方式,最终生成添加了水印的图片。

调用说明:

以函数调用方式调用即可,当然你也可以以类的方式封装,或者你也可以根据需要将此函数进一步细分模块也可以。当然你现在这样用也是没有任何问题的,我已测试过,请放心使用。

其他说明:

由于imagettftext和imagettfbbox函数需要GD库和FreeType库的支持,如果你的运行环境不支持GD库和FreeType库则文字方式就无法实现,你可以用imagestring函数实现给图片添加文字水印,同时设定下text方式下的$logow和$logoh值即可。

imagejpeg函数也可以设置合成的图片质量。

PHP 相关文章推荐
在apache下限制每个虚拟主机的并发数!!!!
Oct 09 PHP
PHP_Flame(Version:Progress)的原代码
Oct 09 PHP
php完全过滤HTML,JS,CSS等标签
Jan 16 PHP
PHP引用符&amp;的用法详细解析
Aug 22 PHP
php获取从百度搜索进入网站的关键词的详细代码
Jan 08 PHP
PHP的switch判断语句的“高级”用法详解
Oct 01 PHP
php中return的用法实例分析
Feb 28 PHP
PHP中余数、取余的妙用
Jun 29 PHP
PHP Post获取不到非表单数据的问题解决办法
Feb 27 PHP
浅谈php调用python文件
Mar 29 PHP
Yii框架响应组件用法实例分析
Sep 04 PHP
PHP实现Markdown文章上传到七牛图床的实例内容
Feb 11 PHP
前端必学之PHP语法基础
Jan 01 #PHP
WordPress中登陆后关闭登陆页面及设置用户不可见栏目
Dec 31 #PHP
WordPress中获取指定分类及其子分类下的文章数目
Dec 31 #PHP
Swoole-1.7.22 版本已发布,修复PHP7相关问题
Dec 31 #PHP
WordPress中给媒体文件添加分类和标签的PHP功能实现
Dec 31 #PHP
简单了解将WordPress中的工具栏移到底部的小技巧
Dec 31 #PHP
WordPress中获取所使用的模板的页面ID的简单方法
Dec 31 #PHP
You might like
全国FM电台频率大全 - 2 天津市
2020/03/11 无线电
Php图像处理类代码分享
2012/01/19 PHP
PHP反射类ReflectionClass和ReflectionObject的使用方法
2013/11/13 PHP
php从memcache读取数据再批量写入mysql的方法
2014/12/29 PHP
解决ThinkPHP关闭调试模式时报错的问题汇总
2015/04/22 PHP
PHP魔术方法以及关于独立实例与相连实例的全面讲解
2016/10/18 PHP
关于实现代码语法标亮 dp.SyntaxHighlighter
2007/02/02 Javascript
JS 各种网页尺寸判断实例方法
2013/04/18 Javascript
使用Meteor配合Node.js编写实时聊天应用的范例
2015/06/23 Javascript
JS实现六位字符密码输入器功能
2016/08/19 Javascript
AngularJS路由切换实现方法分析
2017/03/17 Javascript
jQuery实现简单漂亮的Nav导航菜单效果
2017/03/29 jQuery
angular.JS实现网页禁用调试、复制和剪切
2017/03/31 Javascript
Angular2入门教程之模块和组件详解
2017/05/28 Javascript
Angular2 组件交互实例详解
2017/08/24 Javascript
基于three.js编写的一个项目类示例代码
2018/01/05 Javascript
微信小程序实现滴滴导航tab切换效果
2018/07/24 Javascript
H5+C3+JS实现双人对战五子棋游戏(UI篇)
2020/05/28 Javascript
NodeJS实现同步的方法
2019/03/02 NodeJs
JS实现的碰撞检测与周期移动完整示例
2019/09/02 Javascript
JavaScript代码简化技巧实例解析
2020/09/09 Javascript
用vue设计一个日历表
2020/12/03 Vue.js
[49:35]LGD vs OG 2018国际邀请赛淘汰赛BO3 第二场 8.25
2018/08/29 DOTA
python集合类型用法分析
2015/04/08 Python
Python文档生成工具pydoc使用介绍
2015/06/02 Python
Linux系统上Nginx+Python的web.py与Django框架环境
2015/12/25 Python
python jieba分词并统计词频后输出结果到Excel和txt文档方法
2018/02/11 Python
python正则-re的用法详解
2019/07/28 Python
html5本地存储_动力节点Java学院整理
2017/07/12 HTML / CSS
荟萃全球保健品:维他购
2018/05/09 全球购物
Juice Beauty官网:有机美容产品,护肤与化妆品
2020/06/13 全球购物
澳大利亚头发和美容产品购物网站:OZ Hair & Beauty
2020/03/27 全球购物
10条PHP编程习惯
2014/05/26 面试题
新闻编辑自荐书范文
2014/02/12 职场文书
关于责任的演讲稿
2014/05/20 职场文书
Django drf请求模块源码解析
2021/06/08 Python