<?php
/**
 * reginx 图片处理库
 * @copyright reginx.com
 * $Id: image.lib.php 156 2013-03-05 07:33:00Z reginx $
 */
class image_lib{

    /**
     * 默认支持的图片类型
     *
     * @var unknown_type
     */
    public static $ext = array('jpg' , 'jpeg' , 'gif' , 'png' , 'bmp');

    /**
     * 获取图片信息
     * @abstract
     * @param unknown_type $sfile
     * @return unknown
     */
    public static function getinfo($sfile) {
        if(($sfile = realpath($sfile)) === false){
            core::error(core::L('not-found' , $sfile));
        }
        $info = getimagesize($sfile);
        if($info !== false){
            $ext  = substr($info['mime'] , strpos($info['mime'] , '/') + 1 ,strlen($info['mime']));
            $ext  = $ext == 'jpeg' ? 'jpg' : $ext;
            $ext  = $ext == 'x-ms-bmp' ? 'bmp' : $ext;
            if(!in_array($ext , self::$ext)){
                core::error(core::L('no-support' , $ext . ' : ' . $sfile));
            }
            $info = array(
                'width'     => $info[0],
                'height'    => $info[1],
                'dir'       => dirname($sfile),
                'name'      => basename($sfile , '.' . $ext),
                'ext'       => $ext,
                'size'      => filesize($sfile),
                'mime'      => $info['mime']
            );
        }else{
            $info = array();
        }
        return $info;
    }

    /**
     * 生成缩略图相关属性(剪切方式)
     * @abstract 计算剪切坐标 及 临时缩略图的尺寸
     * @param unknown_type $swidth
     * @param unknown_type $sheight
     * @param unknown_type $twidth
     * @param unknown_type $theight
     * @return unknown
     */
    public static function getcutpix($swidth ,$sheight , $twidth , $theight){
        $ret = array();
        // 宽比
        $wprop  = ($swidth  / $twidth ) === 0 ? 1 : ($swidth  / $twidth);
        // 高比
        $hprop  = ($sheight / $theight) === 0 ? 1 : ($sheight / $theight);

        if($swidth <= $twidth || $sheight <= $theight){
            $ret['top']   = ($sheight - $theight) / 2;
            $ret['left']  = ($swidth  - $twidth ) / 2;
            $ret['width'] = $swidth;
            $ret['height']= $sheight;
        }
        else if ($swidth > $twidth && $sheight > $theight){
            if($wprop > $hprop){
                $ret['top']   = 0;
                $ret['left']  = intval((($swidth / $hprop) - $twidth )/2);
                $ret['width'] = intval($swidth / $hprop);
                $ret['height']= $theight;
            }else{
                $ret['top']   = intval((($sheight / $wprop) - $theight )/2);
                $ret['left']  = 0;
                $ret['width'] = $twidth;
                $ret['height']= intval($sheight / $wprop);
            }
        }
        else{
            if($wprop > $hprop){
                $ret['top']   = intval(($sheight - $theight) / 2);
                $ret['left']  = intval(($swidth - $twidth  ) / 2);
                $ret['width'] = intval($swidth / $hprop);
                $ret['height']= $theight;
            }else{
                $ret['top']   = intval(($sheight - $theight) / 2);
                $ret['left']  = intval(($swidth  - $twidth ) / 2);
                $ret['width'] = $twidth;
                $ret['height']= intval($sheight / $wprop);
            }
        }
        return $ret;
    }

    /**
     * 获取生成缩略图相关参数
     *
     * @param unknown_type $swidth 原图片宽度
     * @param unknown_type $sheight 原图片高度
     * @param unknown_type $twidth 目标宽度
     * @param unknown_type $theight 目标高度
     * @return array
     */
    public static function getthumbpix($swidth ,$sheight , $twidth , $theight){
        $ret = array();
        $outprop = sprintf('%.2f' , $twidth / $theight);
        $tmpprop = $outprop >= 1 ? sprintf('%.2f' , $swidth / $twidth) : sprintf('%.2f' , $sheight / $theight);
        $ret['top']   = 0;
        $ret['left']  = 0;
        $ret['width'] = intval($swidth  / $tmpprop);
        $ret['height']= intval($sheight / $tmpprop);
        return $ret;
    }

    /**
     * 缩略图
     *
     * @param unknown_type $sfile
     * @param unknown_type $outfile
     * @param unknown_type $width
     * @param unknown_type $height
     * @param unknown_type $type
     */
    public static function thumb($sfile , $outfile = 'auto' , $width = 'auto' , $height = 'auto' , $type = 1){
        // 获取图片信息
        $info = self::getinfo($sfile);
        if(empty($info)){
        	return false;
        }
        // 读取原图片
        $simage = null;
        $func   = "imagecreatefrom" . ($info['ext'] == 'jpg' ? 'jpeg' : $info['ext']);
        if(function_exists($func)) {
            $simage = call_user_func($func , $sfile);
        }else{
            core::error(core::L('no-support' , $func));
        }
        // 构建缩略图文件名称
        if(strtolower($outfile) == 'auto'){
            $outfile  = $info['dir'] . DIR_SEP . $info['name'] . '_thumb.' . $info['ext'];
        }
        // 缩略图生成尺寸位置参数
        $pix = array();
        if((int)$type === 1){
            $pix = self::getcutpix($info['width'] , $info['height'] , $width , $height);
        }else{
            $pix = self::getthumbpix($info['width'] , $info['height'] , $width , $height);
        }
        // 创建缩略图
        $thumbimage = false;
        if($info['ext'] != 'gif' && function_exists('imagecreatetruecolor')){
            $thumbimage = imagecreatetruecolor($width , $height);
        }else{
            $thumbimage = imagecreate($width , $height);
        }
        $func = 'image'.($info['ext'] == 'jpg' ? 'jpeg' : $info['ext']);
        // 背景填充 FDFDFD
        //imagecolorallocate($thumbimage, 0x00 , 0x00 , 0x00);
        imagecolorallocate($thumbimage, 0xFD , 0xFD , 0xFD);
        // 创建临时缩略图
        $tmpimage = imagecreatetruecolor($pix['width'],$pix['height']);
        if(function_exists("imagecopyresampled")){
            imagecopyresampled($tmpimage , $simage , 0 , 0 , 0 , 0 , $pix['width'] , $pix['height'] , $info['width'] , $info['height']);
        }else{
            imagecopyresized($tmpimage , $simage , 0 , 0 , 0 , 0 , $pix['width'] , $pix['height'] , $info['width'] , $info['height']);
        }
        // 若为gif/png 设置颜色透明
        if($info['ext'] == 'gif' || $info['ext'] == 'png') {
            imagecolortransparent($thumbimage , imagecolorallocate($thumbimage , 0 , 255 , 0));
        }
        // 对jpeg图形设置隔行扫描
        if($info['ext'] == 'jpg' || $info['ext'] == 'jpeg'){
            imageinterlace($thumbimage , 1);
        }
        // 剪切临时缩略图部分至缩略图
        if((int)$type == 1){
            imagecopy($thumbimage , $tmpimage , 0 , 0 , $pix['left'] , $pix['top'], $width,$height);
        }else{
            imagecopy($thumbimage , $tmpimage , 0 , 0 , 0 , 0 ,$width , $height);
        }
        // 创建图片文件
        call_user_func_array($func , array($thumbimage , $outfile));
        imagedestroy($thumbimage);
        imagedestroy($tmpimage);
    }

    /**
     * 生成图片验证码
     *
     * @param unknown_type $str
     * @param unknown_type $width
     * @param unknown_type $height
     */
    public static function verify($str = '' , $width = 0, $height = 0){
        $width  = intval($width)  ? intval($width)  : (strlen($str) * 10 + 10);
        $height = intval($height) ? intval($height) : 20;
        $img = imagecreatetruecolor($width, $height);
        // 背景颜色.
        $bgcolor     = imagecolorallocate($img , 253 , 253 , 253);
        // 边框颜色
        $bordercolor = imagecolorallocate($img , 99 , 99 , 99);
        // 文字颜色
        $fontcolor   = imagecolorallocate($img , mt_rand(0, 90), mt_rand(0, 160), mt_rand(0, 120));
        // 填充背景色
        imagefilledrectangle($img, 0, 0, $width, $height, $bgcolor);
        // 设置边框颜色
        imagerectangle($img, 0, 0, $width - 1 , $height - 1 , $bordercolor);
        // 干扰线
        for($i = 0 ; $i < 5 ; $i++) {
            $color = imagecolorallocate($img, mt_rand(180 , 250), mt_rand(150 , 250), mt_rand(180 , 250));
            imageline($img, mt_rand( 1, $width - 2), mt_rand(1, $height - 2), mt_rand( $width / 3 , $width - 1 ),
            mt_rand( $height / 3 , $height - 1), $color);
        }
        // 干扰点
        for($i = 0 ; $i < 50 ; $i++) {
            $color = imagecolorallocate($img, mt_rand(120, 255), mt_rand(120, 255), mt_rand(120, 255));
            imagesetpixel($img, mt_rand(2, $width-2), mt_rand(2, $height-2), $color);
        }
        // 写入文字
        imagestring($img, 5, $width / (strlen($str) + 2), $height / 7 , strtoupper($str), $fontcolor);
        // 输出
        header("Cache-Control: max-age=s-maxage=no-cache, must-revalidate");
        header("Content-type: image/png;");
        imagepng($img);
        imagedestroy($img);
    }

    /**
     * 水印
     *
     * @param unknown_type $sfile
     * @param unknown_type $wimage
     * @param unknown_type $outfile
     * @param unknown_type $type
     * @param unknown_type $alpha
     * @return unknown
     */
    public static function water($sfile , $wimage , $outfile = 'auto' , $type = 1){
        $info = self::getinfo($sfile);
        $simage = null;
        $func   = "imagecreatefrom" . ($info['ext'] == 'jpg' ? 'jpeg' : $info['ext']);
        if(function_exists($func)) {
            $simage = call_user_func($func , $sfile);
        }else{
            core::error(core::L('no-support' , $func));
        }
        $isfile = file_exists($wimage);
        $winfo  = array();
        if($isfile){
            $winfo = self::getinfo($wimage);
        }else{
            $winfo = array('width' => strlen($wimage) * 8 , 'height' => '20');
        }
        // 默认左上
        $pos = array('left' => 10, 'top' => 10);
        switch((int)$type){
            // 左下
            case 1:
                    $pos['top'] = $info['height'] - 10 - $winfo['height'];
                break;
            // 右上
            case 2:
                    $pos['left'] = $info['width'] - 10 - $winfo['width'];
                break;
            // 右下
            case 3:
                    $pos['left'] = $info['width']  - 10 - $winfo['width'];
                    $pos['top']  = $info['height'] - 10 - $winfo['height'];
                break;
            // 居中
            case 4:
                    $pos['left'] = intval($info['width']  / 2 ) - intval($winfo['width'] / 2 );
                    $pos['top']  = intval($info['height']  / 2) - intval($winfo['height'] / 2);
                break;
        }
        $sfunc = 'image' . ($info['ext'] == 'jpg' ? 'jpeg' : $info['ext']);
        $outfile = $outfile == 'auto' ? $sfile : $outfile;
        if(!is_dir(dirname($outfile))){
            core::error(core::L('not-found' , dirname($outfile)));
        }
        if($isfile){
            // 原图片尺寸小于 水印图片
            if($info["width"] <= $winfo["width"] || $info['height'] <= $winfo['height']){
                return false;
            }
            $water = null;
            $func  = "imagecreatefrom" . ($winfo['ext'] == 'jpg' ? 'jpeg' : $winfo['ext']);
            if(function_exists($func)) {
                $water = call_user_func($func , $wimage);
            }else{
                core::error(core::L('no-support' , $func));
            }
            // 混色模式
            imagealphablending($water, true);
            imagecopy($simage, $water, $pos['left'] , $pos['top'] , 0 , 0 , $winfo['width'] , $winfo['height'] );
            call_user_func_array($sfunc , array($simage ,$outfile));
            imagedestroy($water);
        }else{
            $fontcolor   = imagecolorallocate($simage ,140 , 140 , 140);
            imagestring($simage , 4, $pos['left'] , $pos['top'] , $wimage, $fontcolor);
            call_user_func_array($sfunc , array($simage ,$outfile));
        }
        imagedestroy($simage);
    }
}
?>