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

分类:PHP | 作者:凹凸曼 | 发表于2011/04/26 怎样批量给图片添加水印(PHP实现)?已关闭评论

现在想在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分类下, 评论已关闭。

目前盖楼

抱歉,评论被关闭

« »