<?php
require_once 'Fun/Common.php';
/**
* 图片处理类
* @author dxk http://hi.baidu.com/1024114660
* @version 2011-08-25
*/
class Class_Image
{
        private $error = '';
        private $maxSize = - 1;
        private $basedir = 'p_w_picpath';
        private $allowTypes = array('p_w_picpath/gif', 'p_w_picpath/jpg', 'p_w_picpath/jpeg',
        'p_w_picpath/pjpeg', 'p_w_picpath/png');
        private $savePath;
        /**
         * 上传文件
         * @param array    $file        上传的文件
         * @param string $fileName      要设置的文件名
         * @param string $dir        保存的目录路径
         * @param mixed    $allowTypes    允许上传的文件类型
         * @param int     $maxSize      允许上传的最大文件大小
         * @return mixed          成功是返回文件保存位置,失败返回false
         */
        public function upload ($file, $fileName = '', $dir = '', $allowTypes = '',
        $maxSize = '')
        {
                if (! empty($maxSize) && is_numeric($maxSize)) {
                        $this->maxSize = $maxSize;
                }
                if (! empty($allowTypes)) {
                        if (is_array($allowTypes)) {
                                $this->allowTypes = array_map('strtolower', $allowTypes);
                        } else {
                                $this->allowTypes = explode(',', strtolower($allowTypes));
                        }
                }
                //检查文件合法性
                if (! $this->check($file)) {
                        return false;
                }
                //设置目录路径
                if (empty($dir)) {
                        $dir = $this->basedir;
                }
                //如果目标目录不存在,则创建它
                if (! file_exists($dir)) {
                        if (! make_dir($dir)) {
                                //创建目录失败
                                $this->error = '创建目录失败' . $dir;
                                return false;
                        }
                }
                //设置图片保存路径
                if (empty($fileName)) {
                        $this->savePath = $dir . '/' . $file['name'];
                } else {
                        $pathinfo = pathinfo($file['name']);
                        $this->savePath = $dir . '/' . $fileName . '.' .
                         $pathinfo['extension'];
                }
                //保存图片(如果存在同名图片会覆盖掉)
                if ($this->move_file($file, $this->savePath)) {
                        return $this->savePath;
                } else {
                        return false;
                }
        }
        /**
         * 生成缩略图
         * @param string $img_path        原图路径
         * @param int    $thumb_width      新图宽度
         * @param int    $thumb_height      新图高度
         * @param string $p_w_picpath_type      新图图片格式
         * @param bool    $is_equal        是否等比缩放
         * @param string $target_path      图片存储目标位置,不包括后缀名,如果为空则和原图在一个目录下如果和原图图片格式一致则覆盖原图
         * @return mixed            成功是返回图片保存位置,失败返回false
         */
        function make_thumb ($img_path, $thumb_width = 0, $thumb_height = 0,
        $p_w_picpath_type = 'png', $is_equal = true, $target_path = '')
        {
                //检查原图是否存在
                if (empty($img_path) || ! is_file($img_path)) {
                        $this->error = '所要处理的图片不存在' . $img_path;
                        return false;
                }
                //是否覆盖原图
                if (! empty($target_path)) {
                        //如果目标目录不存在,则创建它
                        $dir = dirname($target_path);
                        if (! file_exists($dir)) {
                                if (! make_dir($dir)) {
                                        //创建目录失败
                                        $this->error = '创建目录失败' . $dir;
                                        return false;
                                }
                        }
                        $this->savePath = $target_path . '.' . $p_w_picpath_type;
                } else {
                        $this->savePath = dirname($img_path) . '.' . $p_w_picpath_type;
                }
                $p_w_picpath = new Imagick($img_path);
                //根据是否等比缩放生成缩略图
                if (! $p_w_picpath->thumbnailp_w_picpath($thumb_width, $thumb_height,
                $is_equal)) {
                        $this->error = '压缩失败';
                        return false;
                }
                //设置图片格式
                if (! $p_w_picpath->setp_w_picpathformat($p_w_picpath_type)) {
                        $this->error = '设置图片格式失败' . $p_w_picpath_type;
                        return false;
                }
                if ($p_w_picpath->writep_w_picpath($this->savePath)) {
                        $p_w_picpath->destroy();
                        return $this->savePath;
                } else {
                        $p_w_picpath->destroy();
                        $this->error = '压缩图片失败';
                        return false;
                }
        }
        /**
         * 添加水印
         * @param string $img_path        原图路径
         * @param mixed    $water_info      水印图片路径或者水印文字信息数组array('text'=>'','color'=>'#666666',size=20)
         * @param string $target_path      目标图片存放完整路径,如果为空覆盖原图,包括文件名
         * @param int    $water_place      水印位置 1-9
         * @param float    $water_alpha      水印透明度
         * @return  mixed            成功返回图片路径,失败返回false  
         */
        public function make_water ($img_path, $water_info, $target_path = '',
        $water_place = 1, $water_alpha = 0.6)
        {
                //检查原图是否存在
                if (empty($img_path) || ! is_file($img_path)) {
                        $this->error = '所要处理的图片不存在' . $img_path;
                        return false;
                }
                //是否覆盖原图
                if (! empty($target_path)) {
                        //如果目标目录不存在,则创建它
                        $dir = dirname($target_path);
                        if (! file_exists($dir)) {
                                if (! make_dir($dir)) {
                                        //创建目录失败
                                        $this->error = '创建目录失败' . $dir;
                                        return false;
                                }
                        }
                        $this->savePath = $target_path;
                } else {
                        $this->savePath = $img_path;
                }
                $p_w_picpath = new Imagick($img_path);
                $dw = new ImagickDraw();
                if (is_string($water_info)) {
                        //检查水印图片是否存在
                        if (empty($water_info) || ! is_file($water_info)) {
                                $this->error = '水印图片不存在' . $water_info;
                                $p_w_picpath->destroy();
                                $dw->destroy();
                                return false;
                        }
                        //加图片水印
                        $water = new Imagick($water_info);
                        //设置水印透明度
                        $water->setp_w_picpathopacity($water_alpha);
                        $dw->setgravity($water_place); //设置水印位置
                        if (! $dw->composite($water->getp_w_picpathcompose(), 0, 0, 0,
                        0, $water)) {
                                $this->error = '添加水印失败';
                                $water->destroy();
                                return false;
                        }
                        $water->destroy();
                } elseif (is_array($water_info)) {
                        //加文字水印
                        $dw->setfontsize($water_info['size']);
                        $dw->setfillcolor($water_info['color']);
                        $dw->setfont('fonts/simkai.ttf');
                        $dw->setgravity($water_place);
                        $dw->annotation(0, 0, $water_info['text']);
                } else {
                        $p_w_picpath->destroy();
                        $dw->destroy();
                        return false;
                }
                $p_w_picpath->drawp_w_picpath($dw);
                if (! $p_w_picpath->writep_w_picpath($this->savePath)) {
                        $this->error = '生成缩略图失败';
                        $p_w_picpath->destroy();
                        $dw->destroy();
                        return false;
                } else {
                        $p_w_picpath->destroy();
                        $dw->destroy();
                        return $this->savePath;
                }
        }
        /**
         * 检查上传的文件是否合法
         * @param    array  $file    上传的文件
         */
        private function check ($file)
        {
                if ($file['error'] !== 0) {
                        //文件上传失败
                        //捕获错误代码
                        $this->error = $file['error'];
                        return false;
                }
                //文件上传成功,进行自定义规则检查
                //检查文件大小
                if (! $this->checkSize($file['size'])) {
                        $this->error = '上传文件大小不符!';
                        return false;
                }
                //检查文件Mime类型
                if (! $this->checkType($file['type'])) {
                        $this->error = '上传文件MIME类型不允许!';
                        return false;
                }
                //检查是否合法上传
                if (! $this->checkUpload($file['tmp_name'])) {
                        $this->error = '非法上传文件!';
                        return false;
                }
                return true;
        }
        /**
         * 检查文件大小是否合法
         * @param int $size        文件大小
         */
        private function checkSize ($size)
        {
                return ! ($size > $this->maxSize) || (- 1 == $this->maxSize);
        }
        /**
         * 检查文件类型
         * @param string $type      文件类型
         */
        private function checkType ($type)
        {
                if (! empty($this->allowTypes))
                        return in_array(strtolower($type), $this->allowTypes);
                return true;
        }
        /**
         * 检查是否非法提交
         * @param string $filename    文件名
         */
        private function checkUpload ($filename)
        {
                return is_uploaded_file($filename);
        }
        /**
         * 根据目录创建唯一随即文件名
         * @param string $dir      文件存放的目录名
         */
        function unique_name ($dir = '')
        {
                $filename = '';
                while (empty($filename)) {
                        $filename = rand_string();
                        if (file_exists($dir . $filename . '.jpg') ||
                         file_exists($dir . $filename . '.gif') ||
                         file_exists($dir . $filename . '.png')) {
                                $filename = '';
                        }
                }
                return $filename;
        }
        /**
         * 获取错误消息
         */
        public function getErrorMsg ()
        {
                return $this->error;
        }
        /**
         * 移动文件到目标位置
         * @param array $file      文件
         * @param string $target    目标文件
         */
        function move_file ($file, $target)
        {
                if (isset($file['error']) && $file['error'] > 0) {
                        return false;
                }
                if (move_uploaded_file($file['tmp_name'], $target)) {
                        return true;
                } elseif (copy($file['tmp_name'], $target)) {
                        return true;
                }
                return true;
        }
}