<?php
namespace imcat;

//图像:缩略图/水印处理
class comImage{

    // 压缩一个图片目录
    public static function compdir($dir='', $size=500, $max=2400){
        $res = array();
        $lists = comFiles::listScan($dir);
        foreach ($lists as $file=>$row) {
            $full = "$dir/$file";
            $res[] = self::compcut($full, $max);
            if(strpos($file,'.jpg') && $row[1]>$size*1024){ 
                self::compress($full, 80);
            }
        }
        return $res;
    }

    // 限制图片大小, 针对jpg
    public static function compcut($full, $max=2400){
        $info = self::info($full);
        if($info['width']>$max || $info['height']>$max){
            if($info['width']>$info['height']){
                $h = $info['height']*$max/$info['width'];
                $w = $max;
            }else{
                $w = $info['width']*$max/$info['height'];
                $h = $max;
            }
            self::thumb($full, $full, $w, $h); 
        }
        return $info;
    }

    # 压缩图片, JPEG支持好，PNG良好，GIF不支持
    public static function compress($target, $quality=75){
        if($srcInfo = @getimagesize($target)){
            switch ($srcInfo[2]){
                case 1:
                    break;
                case 2:
                    $srcim =imagecreatefromjpeg($target);
                    imagejpeg($srcim,$target,$quality);
                    break;
                case 3:
                    $srcim =imagecreatefrompng($target);
                    $pngQuality = ($quality - 100) / 11.111111;
                    $pngQuality = round(abs($pngQuality));
                    imagepng($srcim,$target,$pngQuality);
                    break;
                default:
                    return;
            }
        }
    }
    
    /** 取得图像信息
     * @param string $image 图像文件名
     * @return mixed
     */
    static function info($img) {
        $imageInfo = getimagesize($img); // riff webpvp8 格式，不能获取到信息
        if( $imageInfo!== false)
         {
            $imageType = strtolower(substr(image_type_to_extension($imageInfo[2]),1));
            $imageSize = filesize($img);
            $info = array(
                "width"=>$imageInfo[0],
                "height"=>$imageInfo[1],
                "type"=>$imageType,
                "size"=>$imageSize,
                "mime"=>$imageInfo['mime']
            );
            return $info;
        }else {
            return false;
        }
    }

    /** 生成缩略图 (补灰边,超比例截取)
     * @param string $image  原图
     * @param string $thumbname 缩略图文件名
     * @param string $maxWidth  宽度
     * @param string $maxHeight  高度
     * @param boolean $interlace 启用隔行扫描
     * @param string $type 图像格式 
     */
    static function thumb($image,$thumbname,$maxWidth=120,$maxHeight=90,$interlace=true,$type=''){
        $ire = self::_thpos($image, $maxWidth, $maxHeight);
        if(!$ire) return false;
        extract($ire); 
        // 载入原图
        $func = 'ImageCreateFrom'.($type=='jpg'?'jpeg':$type);
        $srcImg = $func($image);
        // 创建缩略图
        $func = ($type!='gif' && function_exists('imagecreatetruecolor')) ? 'imagecreatetruecolor' : 'imagecreate';
        $thumbImg = $func($maxWidth, $maxHeight);
        // 填充白底
        $bg_color = imagecolorallocate($thumbImg, 204,204,204);
        imagefill($thumbImg,0,0,$bg_color);
        // 复制图片
        $func = function_exists("ImageCopyResampled") ? "ImageCopyResampled" : "ImageCopyResized";
        $func($thumbImg,$srcImg, $ox,$oy, $ix,$iy, $ow,$oh, $iw,$ih);
        if('gif'==$type || 'png'==$type) { // 设置为透明色
            imagecolortransparent($thumbImg,$bg_color);
        }else{ // 对jpeg图形设置隔行扫描
            if('jpg'==$type || 'jpeg'==$type) imageinterlace($thumbImg, $interlace?1:0);
        }
        // 生成图片
        $func = 'image'.($type=='jpg'?'jpeg':$type);
        $func($thumbImg,$thumbname);
        imagedestroy($thumbImg);
        imagedestroy($srcImg);
        return $thumbname;
    }
    // {staticroot}/icons/basic/demo_pic1.jpg
    // http://img.domain.com/imcat/demo/abc.jpg
    // {ures}/demo/abc.jpg
    static function thpic($val,$resize){
        // 还原完整路径
        $orgd = str_replace(array('{uresroot}','{staticroot}'),array(DIR_URES,DIR_STATIC),$val);
        $orgp = str_replace(array('{uresroot}','{staticroot}'),array(PATH_URES,PATH_STATIC),$val);
        $repath = read('repath','sy');
        $redir = empty($repath['dir']) ? array() : $repath['dir'];
        $reatt = empty($repath['att']) ? array() : $repath['att'];
        if(!empty($redir)){
            $orgd = str_replace(array_keys($redir),array_values($redir),$orgd); 
        }
        if(!empty($reatt)){
            $orgp = str_replace(array_keys($reatt),array_values($reatt),$orgp); 
        }
        // 目标路径
        $ext = strrchr($val,'.');
        $objd = str_replace($ext,"-$resize$ext",$orgd);
        $objp = str_replace($ext,"-$resize$ext",$orgp);
        if(strpos($objp,'://')>0){ // out-cdn/ftp:根据具体情况修改了...
            if(strpos($orgp,PATH_URES)===false) return $orgp; // http://img.xcdn.com/dir/file.ext
            $scfg = glbConfig::read('store','ex');
            if(!isset($scfg[$scfg['type']]['cut_ures'])) return $orgp;
            $cutp = $scfg[$scfg['type']]['cut_ures']; // http://domain.com/cut.php?
            return str_replace(array("(size)","(img)"),array($resize,$orgp),$cutp); 
        }elseif(file_exists($objd)){ // 有缩略图
            return $objp;
        }elseif(file_exists($orgd)){ // (本地)有原图片,
            $size = explode('x',$resize);
            $res = self::thumb($orgd,$objd,$size[0],$size[1]);
            return $res ? $objp : $orgp;
        }
        return $orgp;
    }
    
    // 描边文字水印
    static function wmtext($image, $text, $waterPos=array(9,10)){
        //读取原图像文件
        $imageInfo = self::info($image);
        $image_w = $imageInfo['width']; //取得水印图片的宽
        $image_h = $imageInfo['height']; //取得水印图片的高
        //读取水印文字配置
        $waterInfo = glbConfig::read('wmark','sy');
        $w = $waterInfo['width']; //取得水印图片的宽
        $h = $waterInfo['height']; //取得水印图片的高ctext
        if($image_w<=$w || $image_h<=$h){
            return 'file too SMALL!';
        }
        $func = "imagecreatefrom" . $imageInfo['type'];
        $image_im = $func($image);
        $pos = self::_wpos($image_w, $image_h, $w, $h, $waterPos);
        $posX = $pos[0]; $posY = $pos[1]; 
        //设定图像的混色模式
        imagealphablending($image_im, true);
        foreach(array('ctext','cborder') as $k){
            $$k = imagecolorallocate($image_im, $waterInfo[$k], $waterInfo[$k], $waterInfo[$k]);
        }
        $tfont = DIR_STATIC.$waterInfo['font'];
        $ia = array(1,-1,-1,1,0);
        $ja = array(1,1,-1,-1,0);
        for($i=0;$i<5;$i++){ //先4个象限移动1px,再到0,实现描边(Peace)
            $tcolor = empty($ia[$i]) ? $ctext : $cborder;
            imagettftext($image_im, $waterInfo['size'], 0, $posX+$ia[$i], $posY+$ja[$i], $tcolor, $tfont, $text); 
        }
        //生成水印后的图片
        $func = "image" . $imageInfo['type'];
        $func($image_im, $image);
        //释放内存
        $imageInfo = NULL;
        imagedestroy($image_im);
    }
    // 图片水印
    static function wmpic($image, $water, $waterPos=array(9,10)){
        //读取原图像文件
        $imageInfo = self::info($image);
        $image_w = $imageInfo['width']; //取得水印图片的宽
        $image_h = $imageInfo['height']; //取得水印图片的高
        //读取水印文件
        $waterInfo = self::info($water);
        $w = $waterInfo['width']; //取得水印图片的宽
        $h = $waterInfo['height']; //取得水印图片的高
        if($image_w<=$w || $image_h<=$h){
            return 'file too SMALL!';
        }
        $func = "imagecreatefrom" . $imageInfo['type'];
        $image_im = $func($image);
        $func = "imagecreatefrom" . $waterInfo['type'];
        $water_im = $func($water);
        $pos = self::_wpos($image_w, $image_h, $w, $h, $waterPos);
        $posX = $pos[0]; $posY = $pos[1]; 
        //设定图像的混色模式
        imagealphablending($image_im, true);
        imagecopy($image_im, $water_im, $posX, $posY, 0, 0, $w, $h); //拷贝水印到目标文件
        //生成水印后的图片
        $func = "image" . $imageInfo['type'];
        $func($image_im, $image);
        //释放内存
        $waterInfo = $imageInfo = NULL;
        imagedestroy($image_im);
        imagedestroy($water_im);
    }
     /** 图片/文字:水印(watermark)
     * @$image  原图
     * @$type 水印类型：0-按配置, pic-配置中的图片, text-配置中的文字, 图片path-图片水印, 其它-文字内容
     * @$$waterPos 水印位置
       - (0-9,margin=10) 0-9:0为随机,其他代表上中下9个部分位置; margin:水印边距
       - (-10,20)        距离下方10px, 右方20px
     */
    static function wmark($image, $type=0, $waterPos=array()){
        if(!file_exists($image)){ //检查图片是否存在
            return 'file NOT exists!';
        }
        $wcfgs = glbConfig::read('wmark','sy');
        if(empty($waterPos)) $waterPos = $wcfgs['pos'];
        if(empty($type) || in_array($type,array('pic','text'))){
            if(empty($type)) $type = $wcfgs['type'];
            if($type=='pic' && file_exists(DIR_VIEWS.$wcfgs['plogo'])){
                return self::wmpic($image, DIR_VIEWS.$wcfgs['plogo'], $waterPos);
            }else{
                return self::wmtext($image, $wcfgs['stext'], $waterPos);
            }
        }elseif(file_exists($type)){
            return self::wmpic($image, $type, $waterPos);
        }else{
            return self::wmtext($image, $type, $waterPos);
        }
    }
    // 水印位置(0-9,margin=10), (+-x,+-y)
    static function _wpos($image_w, $image_h, $w, $h, $waterPos=array(0,10)){
        $pos = $x = $waterPos[0]; //九宫格位置,坐标位置x
        $gap = $y = $waterPos[1]; //九宫格边距,坐标位置y
        $posX = $posY = 0;
        if(abs($pos)<10){
            switch ($pos) {
            case 1: //1为顶端居左
                $posX = $gap;
                $posY = $gap;
            break;
            case 2: //2为顶端居中
                $posX = ($image_w - $w) / 2;
                $posY = $gap;
            break;
            case 3: //3为顶端居右
                $posX = $image_w - $w - $gap;
                $posY = $gap;
            break;
            case 4: //4为中部居左
                $posX = $gap;
                $posY = ($image_h - $h) / 2;
            break;
            case 5: //5为中部居中
                $posX = ($image_w - $w) / 2;
                $posY = ($image_h - $h) / 2;
            break;
            case 6: //6为中部居右
                $posX = $image_w - $w - $gap;
                $posY = ($image_h - $h) / 2;
            break;
            case 7: //7为底端居左
                $posX = $gap;
                $posY = $image_h - $h - $gap;
            break;
            case 8: //8为底端居中
                $posX = ($image_w - $w) / 2;
                $posY = $image_h - $h - $gap;
            break;
            case 9: //9为底端居右
                $posX = $image_w - $w - $gap;
                $posY = $image_h - $h - $gap;
            break;
            default: //0,随机
                $posX = rand(0, ($image_w - $w));
                $posY = rand(0, ($image_h - $h));
            break;
            }
            if($posX<0) $posX = rand(0, ($image_w - $w));    
            if($posY<0) $posX = rand(0, ($image_h - $h));    
        }else{
            $posX = $x<0 ? $image_w + $x: $x;
            $posY = $y<0 ? $image_h + $y: $y;
        }
        return array($posX, $posY);
    }

    static function _thpos($image, $ow, $oh){
        $img = self::info($image);
        if(!$img) return false;
        $iw = $img['width'];
        $ih = $img['height'];
        $res = array(
            'type'=>$img['type'],
            'ix'=>0,'iy'=>0,'iw'=>$iw,'ih'=>$ih,
            'ox'=>0,'oy'=>0,'ow'=>$ow,'oh'=>$oh,
        );
        if($iw>$ow && $ih>$oh){
            $is = $iw/$ih; $os = $ow/$oh;
            if($is>$os){ // 太宽(截取)
                $ew = $ih * $os;
                $dw = intval(($iw-$ew)/2);
                $res['ix'] = $dw; $res['iw'] = $ew;
            }elseif($os>$is){ // 太高(截取)
                $eh = $iw / $os;
                $dh = intval(($ih-$eh)/2);
                $res['iy'] = $dh; $res['ih'] = $eh;
            }
        }elseif($iw>$ow){ // 太宽(截取+补边)
            $dw = intval(($iw-$ow)/2);
            $dh = intval(($oh-$ih)/2);
            $res['oy'] = $dh; $res['oh'] = $ih;
            $res['ix'] = $dw; $res['iw'] = $ow;
        }elseif($ih>$oh){ // 太高(截取+补边)
            $dw = intval(($ow-$iw)/2);
            $dh = intval(($ih-$oh)/2);
            $res['ox'] = $dw; $res['ow'] = $iw;
            $res['iy'] = $dh; $res['ih'] = $oh;
        }else{ // 
            return false; //$res
        }
        return $res; 
    }

}

/*

*/
