抱歉,评论被关闭
怎样批量给图片添加水印(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
日志信息 »
该日志于2011-04-26 03:44由 凹凸曼 发表在PHP分类下,
评论已关闭。
目前盖楼


