怎样批量给图片添加水印(PHP实现)?

分类:PHP | 作者:凹凸曼 | 发表于2011/04/26

现在想在WordPress上传图片的时候加水印,目前采用了一个Watermark Reloaded插件

水印:凹凸曼

但是问题是以前上传的图片没有水印呢!

怎样把以前的图片加上水印呢?

我就继承了Watermark Reloaded水印基类

基类做了一部分修改

并且在子类里完成所有处理–多级目录图片都支持

一、目录结构如下图所示:

mypic—图片文件夹

STCAIYUN.TTF–字体

watermark-reloaded.php—PHP源文件

二、文件源码—watermark-reloaded.php

如下:

<?php
//基类
class Watermark_Reloaded {
 /**
  * Watermark RELOADED version
  *
  * @var string
  */
 public $version                 = '1.2.4';
 
 /**
  * Array with default options
  *
  * @var array
  */
 protected $_options             = array(
  'watermark_donated'  => 0,
  'watermark_hide_nag' => 0,
  'watermark_on'       => array(),
  'watermark_position' => 'bottom_right',
  'watermark_offset'   => array(
   'x' => 5,
   'y' => 5
  ),
  'watermark_text'     => array(
   'value' => '凹凸曼',
   'font'  => 'STCAIYUN.TTF',   //在系统里copy一种字体到你的源文件watermark-reloaded.php下
   'size'  => 20,
   'color' => 'FF9933'
  )
 );
 
 /**
  * Plugin work path
  *
  * @var string
  */
 protected $_plugin_dir          = null;
 
 /**
  * Settings url
  *
  * @var string
  */
 protected $_settings_url        = null;
 
 /**
  * Path to dir containing fonts
  *
  * @var string
  */
 protected $_fonts_dir           = 'fonts/';
 
 /**
  * Get option by setting name with default value if option is unexistent
  *
  * @param string $setting
  * @return mixed
  */
 protected function get_option($setting) {
  return get_option($setting, $this->_options[$setting]);
 }
 
 /**
  * Get array with options
  *
  * @return array
  */
 private function get_options() {
  $options = array();
  
  // loop through default options and get user defined options
  foreach($this->_options as $option => $value) {
   $options[$option] = $this->get_option($option);
  }
  
  return $options;
 }
 
 /**
  * Merge configuration array with the default one
  *
  * @param array $default
  * @param array $opt
  * @return array
  */
 private function mergeConfArray($default, $opt) {
  foreach($default as $option => $values) {
   if(!empty($opt[$option])) {
    $default[$option] = is_array($values) ? array_merge($values, $opt[$option]) : $opt[$option];
    $default[$option] = is_array($values) ? array_intersect_key($default[$option], $values) : $opt[$option];
   }
  }
  return $default;
    }
 
 /**
  * Plugin installation method
  */
 public function activateWatermark() {
  // record install time
  add_option('watermark_installed', time(), null, 'no');
    
  // loop through default options and add them into DB
  foreach($this->_options as $option => $value) {
   add_option($option, $value, null, 'no'); 
  }
 }
 
 /**
  * Create preview for admin
  *
  * @param array $opt
  */
 public function createPreview(array $opt) {
  // merge custom settings with default settings
  $opt = $this->mergeConfArray($this->_options, $opt);
  
  // calculate required size of image
  $bbox = $this->calculateBBox($opt);
  $size = array(
   'width'  => $bbox['width']  + $this->_options['watermark_offset']['x'] * 2,
   'height' => $bbox['height'] + $this->_options['watermark_offset']['y'] * 2
  );
  // Create the image
  $image = imagecreatetruecolor($size['width'], $size['height']);
  // Add some background to image (#CCCCCC)
  $color = imagecolorallocate($image, 204, 204, 204);
  imagefilledrectangle($image, 0, 0, $size['width'], $size['height'], $color);
  
  // And finaly write text to image
  $this->imageAddText($image, $opt);
  
  // Set the content-type
  header('Content-type: image/png');
  
  // Output the image using imagepng()
  imagepng($image);
  imagedestroy($image);
 }
 
 /**
  * Apply watermark to selected image sizes
  *
  * @param array $data
  * @return array
  */
 public function applyWatermark($data) {
  // get settings for watermarking
  $upload_dir   = wp_upload_dir();
  $watermark_on = $this->get_option('watermark_on');
  // loop through image sizes ...
  foreach($watermark_on as $image_size => $on) {
   if($on == true) {
    switch($image_size) {
     case 'fullsize':
      $filepath = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . $data['file'];
      break;
     default:
      if(!empty($data['sizes']) && array_key_exists($image_size, $data['sizes'])) {
       $filepath = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . dirname($data['file']) . DIRECTORY_SEPARATOR . $data['sizes'][$image_size]['file'];
      } else {
       // early getaway
       continue 2;
      } 
    }
    
    // ... and apply watermark
    $this->doWatermark($filepath);
   }
  }
  // pass forward attachment metadata
  return $data;
 }
 
 /**
  * Apply watermark to certain image
  *
  * @param string $filepath
  * @return boolean
  */
 public function doWatermark($filepath) {
  // get image mime type
  $mime_type =strrchr(strtolower($filepath),'.');
  if($mime_type=='.jpg'){
   $mime_type = 'image/jpeg';
  }else if($mime_type=='.png'){
   $mime_type = 'image/png';
  }else if($mime_type=='.gif'){
   $mime_type = 'image/gif';
  }
  //$mime_type = 'image/jpeg';
  
  // get watermark settings
  $options = $this->_options;
  // get image resource
  $image = $this->getImageResource($filepath, $mime_type);
  // add text watermark to image
  $this->imageAddText($image, $options);
  // save watermarked image
  return $this->saveImageFile($image, $mime_type, $filepath);
 }
 
 /**
  * Add watermark text to image
  *
  * @param resource $image
  * @param array $opt
  * @return resource
  */
 private function imageAddText($image, array $opt) {
  // allocate text color
  $color  = $this->imageColorAllocateHex($image, $opt['watermark_text']['color']);
  
  // calculate watermark position and get full path to font file
  $offset = $this->calculateOffset($image, $opt);
  $opt    = $this->getFontFullpath($opt);
  // Add the text to image
  imagettftext($image, $opt['watermark_text']['size'], 0, $offset['x'], $offset['y'], $color, $opt['watermark_text']['font'], $opt['watermark_text']['value']);
  
  return $image;
 }
 
 /**
  * Allocate a color for an image from HEX code
  *
  * @param resource $image
  * @param string $hexstr
  * @return int
  */
 private function imageColorAllocateHex($image, $hexstr) {
  $int = hexdec($hexstr);
  return imagecolorallocate($image,
   0xFF & ($int >> 0x10),
   0xFF & ($int >> 0x8),
   0xFF & $int
  );
 }
 
 /**
  * Calculate offset acording to watermark alignment
  *
  * @param resource $image
  * @param array $opt
  * @return array
  */
 private function calculateOffset($image, array $opt) {
  $offset = array('x' => 0, 'y' => 0);
  // get image size and calculate bounding box
  $isize  = $this->getImageSize($image);
  $bbox   = $this->calculateBBox($opt);
  list($ypos, $xpos) = explode('_', $opt['watermark_position']);
  
  // calculate offset according to equations bellow
  switch($xpos) {
   default:
   case 'left':
    $offset['x'] = 0 - $bbox['top_left']['x'] + $opt['watermark_offset']['x'];
    break;
   case 'center':
    $offset['x'] = ($isize['x'] / 2) - ($bbox['top_right']['x'] / 2) + $opt['watermark_offset']['x'];
    break;
   case 'right':
    $offset['x'] = $isize['x'] - $bbox['bottom_right']['x'] - $opt['watermark_offset']['x'];
    break;
  }
  
  switch($ypos) {
   default:
   case 'top':
    $offset['y'] = 0 - $bbox['top_left']['y'] + $opt['watermark_offset']['y'];
    break;
   case 'middle':
    $offset['y'] = ($isize['y'] / 2) - ($bbox['top_right']['y'] / 2) + $opt['watermark_offset']['y'];
    break;
   case 'bottom':
    $offset['y'] = $isize['y'] - $bbox['bottom_right']['y'] - $opt['watermark_offset']['y'];
    break;
  }
  return $offset;
 }
 
 /**
  * Get array with image size
  *
  * @param resource $image
  * @return array
  */
 private function getImageSize($image) {
  return array(
   'x' => imagesx($image),
   'y' => imagesy($image)
  );
 }
 
 /**
  * Calculate bounding box of watermark
  *
  * @param array $opt
  * @return array
  */
 private function calculateBBox(array $opt) {
  // http://ruquay.com/sandbox/imagettf/
  $opt = $this->getFontFullpath($opt);
  
  $bbox = imagettfbbox(
   $opt['watermark_text']['size'],
   0,
   $opt['watermark_text']['font'],
   $opt['watermark_text']['value']
  );
  $bbox = array(
   'bottom_left'  => array(
    'x' => $bbox[0],
    'y' => $bbox[1]
   ),
   'bottom_right' => array(
    'x' => $bbox[2],
    'y' => $bbox[3]
   ),
   'top_right'    => array(
    'x' => $bbox[4],
    'y' => $bbox[5]
   ),
   'top_left'     => array(
    'x' => $bbox[6],
    'y' => $bbox[7]
   )
  );
  
  // calculate width & height of text
  $bbox['width']  = $bbox['top_right']['x'] - $bbox['top_left']['x'];
  $bbox['height'] = $bbox['bottom_left']['y'] - $bbox['top_left']['y'];
  
  return $bbox;
 }
 
 /**
  * Get fullpath of font
  *
  * @param array $opt
  * @return unknown
  */
 private function getFontFullpath(array $opt) {
  $opt['watermark_text']['font'] = $opt['watermark_text']['font'];
  
  return $opt;
 }
 
 /**
  * Get image resource accordingly to mimetype
  *
  * @param string $filepath
  * @param string $mime_type
  * @return resource
  */
 private function getImageResource($filepath, $mime_type) {
  switch ( $mime_type ) {
   case 'image/jpeg':
    return imagecreatefromjpeg($filepath);
   case 'image/png':
    return imagecreatefrompng($filepath);
   case 'image/gif':
    return imagecreatefromgif($filepath);
   default:
    return false;
  }
 }
 
 /**
  * Save image from image resource
  *
  * @param resource $image
  * @param string $mime_type
  * @param string $filepath
  * @return boolean
  */
 private function saveImageFile($image, $mime_type, $filepath) {
  switch ( $mime_type ) {
   case 'image/jpeg':
    return imagejpeg($image, $filepath,90);
   case 'image/png':
    return imagepng($image, $filepath);
   case 'image/gif':
    return imagegif($image, $filepath);
   default:
    return false;
  }
 }
}
//author:凹凸曼(lyc)
//email:jar-c@163.com
//批处理图片(添加水印)
class BatchPic extends Watermark_Reloaded{
 private $dirn=''; 
 private $picdir='';        //图片目录
 private $ds=DIRECTORY_SEPARATOR;
 public function __construct($dir='',$picdir=''){
  if(empty($dir)||empty($picdir)){
   throw new Exception('BATCH IMAGE ERROR:params empty!');
  }
  $this->dirn=$dir;
  $this->picdir=$picdir;
 
 }
 public function run(){
  
  $this->picdir=DIRECTORY_SEPARATOR.$this->picdir;          
  $parrent=$this->dirn.$picdir;                              //绝对路径
  $this->batch($parrent);
 
     
 
 
 }
    private function batch($pdir){
            if($filelist=$this->dirFile($pdir)){
             foreach($filelist as $k=>$v){
              if($k==0||$k==1){
                continue;
              }
              if(in_array(strtolower(substr(strrchr($v,"."),1)),array('gif','jpg','png'))){
                 $this->doWatermark($pdir.$this->ds.$v);
              }else if(is_dir($pdir.$this->ds.$v)){
               $this->batch($pdir.$this->ds.$v);
              }else{
             
                continue;
              }
             
             }
            
            }
    }   
     //获取指定目录下文件及文件目录
    private function dirFile($dirname){
       $file=array();
       $f=opendir($dirname);
       while($flist=readdir($f)){
         $file[]=$flist;
       }
       return $file;
    }
}
/**测试区**************/
$dir=dirname(__FILE__);       
$picdir='mypic';           //图片目录
$bp=new BatchPic($dir,$picdir);
$bp->run();
echo 'deal success'; 
/**end***************/
?>

备注:这个基类里有部分是WordPress的函数,我们不用它所以就没有删除,这上面的类只用于批量处理图片水印

啊哈搞定了,这下我以前发的图片都有水印了!

懂程序真好,搞一个批处理,去掉重复处理,多么巴适啊!

本文出自 “凹凸曼” 博客,请务必保留此出处 http://www.apoyl.com/?p=631

Tag:

日志信息 »

该日志于2011-04-26 03:44由 凹凸曼 发表在PHP分类下, 你可以发表评论。除了可以将这个日志以保留源地址及作者的情况下引用到你的网站或博客,还可以通过RSS 2.0订阅这个日志的所有评论。

目前盖楼 (0)层:

发表评论 »

« »