"jpeg", ); public $font; protected static $instance; function __construct(){ $this->font = Yii::app()->basePath."/../css/fonts/yahei_mono.ttf"; } protected static function instance(){ if(!is_object(self::$instance)){ self::$instance = new self(); } return self::$instance; } public static function revertType(&$type){ if(isset(self::$typeMappings[$type])){ $type = self::$typeMappings[$type]; } return true; } public static function destroy($res){ return is_resource($res) ? imagedestroy($res) : false; } public static function create($width, $height, $color = array(255, 255, 255, 100)){ if(!$width || !$height) return false; $src = imagecreatetruecolor($width, $height); if(!($color = self::getColor($src, $color))) return false; imagealphablending($src, true); imagefill($src, 0, 0, $color); imagesavealpha($src, true); return is_resource($src) ? $src : false; } public static function createFromFile($srcFile){ if(!is_file($srcFile)) return false; ($type = File::getExt($srcFile)) and self::revertType($type); switch($type){ case "jpeg": $src = imagecreatefromjpeg($srcFile); break; case "png": $src = imagecreatefrompng($srcFile); break; case "gif": $src = imagecreatefromgif($srcFile); break; default: return false; break; } imagealphablending($src, true); imagesavealpha($src, true); return is_resource($src) ? $src : false; } public static function createFromFiles($files){ $srcs = array(); if(!Arr::isAvailable($files)){ foreach($files as $file){ if(is_file($file) && is_resource($src = self::createFromFile($file))) $srcs[md5_file($file)] = $src; } } return $srcs; } public static function setColor(&$src, $rgb = array()){ if(!is_resource($src) || !Number::isInt($color = self::getColor($src, $rgb))) return false; imagealphablending($src, true); imagefill($src, 0, 0, $color); imagesavealpha($src, true); return true; } public static function saveAs($res, $file){ if(!is_resource($res) || !$file) return false; if(!File::mkdir(File::getPath($file))) return false; $ext = File::getExt($file); switch($ext){ case "jpeg": $rs = imagejpeg($res, $file); break; case "png": $rs = imagepng($res, $file); break; case "gif": $rs = imagegif($res, $file); break; default: return false; break; } return $rs ? true : false; } public static function getColor($src, $rgb){ if(!Arr::isAvailable($rgb)) return null; $count = count($rgb); if($count != 3 && $count != 4) return null; if($count == 4){ list($r, $g, $b, $a) = $rgb; $color = imagecolorallocatealpha($src, $r, $g, $b, $a); } else if($count == 3){ list($r, $g, $b) = $rgb; $color = imagecolorallocate($src, $r, $g, $b); } return $color; } public static function fillRectangle(&$src, $rectangle = array()){ if(!is_resource($src) || !Arr::isAvailable($rectangle, array("w", "h", "x", "y", "color"))) return false; if(!($rectangle["color"] = self::getColor($src, $rectangle["color"]))) return false; return imagefilledrectangle($src, $rectangle["x"], $rectangle["y"], $rectangle["x"] + $rectangle["w"], $rectangle["y"] + $rectangle["h"], $rectangle["color"]); } public static function getImageResSize($res){ $imageSize = array(); $file = sys_get_temp_dir()."/".Random::uuid().".png"; if(self::saveAs($res, $file)){ $imageSize = getimagesize($file); $imageSize = array($imageSize[0], $imageSize[1]); File::rm($file); } return $imageSize; } private function _getStringRectangleSize($string, $font){ $size = array(); if($string && isset($font["size"]) && Number::isNumeric($font["size"]) && $font["size"] > 0){ if(!isset($font["angle"]) || !Number::isNumeric($font["angle"])) $font["angle"] = 0; $size = imageftbbox($font["size"], $font["angle"], $this->font, $string); $size = array($size[2] - $size[0], $size[7] - $size[1]); $size = array(abs($size[0]), abs($size[1])); } return $size; } public static function getStringRectangleSize($string, $font){ return self::instance()->_getStringRectangleSize($string, $font); } private function _sign(&$src, $content, $font = array()){ if(!is_resource($src) || !$content || !Arr::isAvailable($font, array("size", "color", "x", "y")) || !Number::isInt($fontColor = self::getColor($src, $font["color"])) || !($imageSize = self::getImageResSize($src))) return false; if(!($stringRectangleSize = self::getStringRectangleSize($content, $font))) return false; $fontYOffset = $stringRectangleSize[1] - 3; list($font["w"], $font["h"]) = $stringRectangleSize; $position = self::calcPosition($font, array("w" => $imageSize[0], "h" => $imageSize[1])); $position[1] += $fontYOffset; list($font["x"], $font["y"]) = $position; if(!isset($font["angle"]) || !Number::isInt($font["angle"])){ $font["angle"] = 0; } $rs = imagefttext($src, $font["size"], $font["angle"], $font["x"], $font["y"], $fontColor, $this->font, $content); return $rs ? true : false; } public static function sign(&$src, $content, $font = array()){ return self::instance()->_sign($src, $content, $font); } public static function zoom(&$src, $size){ if(!is_resource($src) || (!Arr::isAvailable($size) && !Number::isFloat($size))) return false; $srcSize = self::getImageResSize($src); if(Number::isNumeric($size)) $size = array(Number::truncateDecimal($srcSize[0] * $size), Number::truncateDecimal($srcSize[1] * $size)); $res = $src; $src = self::create($size[0], $size[1]); return imagecopyresampled( $src, $res, 0, 0, 0, 0, $size[0], $size[1], $srcSize[0], $srcSize[1] ); } public static function calcPosition($elementInfo, $containerInfo){ if(!Arr::isAvailable($elementInfo, array("w", "h", "x", "y")) || !Arr::isAvailable($containerInfo, array("w", "h"))) return array(); $param = array(); $param["x"] = trim($elementInfo["x"]); $param["y"] = trim($elementInfo["y"]); $param["x"] = str_replace(" ", " ", $param["x"]); $param["y"] = str_replace(" ", " ", $param["y"]); $param["x"] = explode(" ", $param["x"], 2); $param["y"] = explode(" ", $param["y"], 2); $elementInfo["x"] = 0; foreach($param["x"] as $key => $val){ if(empty($val)) continue; if(Number::isNumeric($val)){ $elementInfo["x"] += Number::truncateDecimal($val, 1); } else{ if($val == "left"){ $elementInfo["x"] += 0; } else if($val == "center"){ $elementInfo["x"] += Number::truncateDecimal(($containerInfo["w"] - $elementInfo["w"]) / 2, 1); } else if($val == "right"){ $elementInfo["x"] += Number::truncateDecimal($containerInfo["w"] - $elementInfo["w"], 1); } } } $elementInfo["y"] = 0; foreach($param["y"] as $key => $val){ if(empty($val)) continue; if(Number::isNumeric($val)){ $elementInfo["y"] += Number::truncateDecimal($val, 1); } else{ if($val == "top"){ $elementInfo["y"] += 0; } else if($val == "center"){ $elementInfo["y"] += Number::truncateDecimal(($containerInfo["h"] - $elementInfo["h"]) / 2, 1); } else if($val == "bottom"){ $elementInfo["y"] += Number::truncateDecimal($containerInfo["h"] - $elementInfo["h"], 1); } } } return array($elementInfo["x"], $elementInfo["y"]); } public static function crop(&$src){ $params = func_get_args(); if(!is_resource($src) || !isset($params[1]) || !Arr::isAvailable($params[1], array("x", "y", "w", "h"))) return false; if(isset($params[2]) && !Arr::isAvailable($params[2], array("x", "y", "w", "h"))) return false; $params = Arr::getVals($params, array(0, 1, 2)); $imageSize = self::getImageResSize($src); if(!isset($params[2])){ $vals = Arr::getVals($params[1], array( "destX" => "x", "destY" => "y", "destW" => "w", "destH" => "h", "color" => "color", )); extract($vals); return imagecopyresampled( $src, $src, 0, 0, $destX, $destY, $destW, $destH, $destW, $destH ); } else{ $elementInfo = Arr::getVals($params[1], array("x", "y", "w", "h")); $containerInfo = Arr::getVals($params[2], array("x", "y", "w", "h")); if(!($position = self::calcPosition(array("w" => $elementInfo["w"], "h" => $elementInfo["h"], "x" => $containerInfo["x"], "y" => $containerInfo["y"]), $containerInfo))) return false; $containerInfo["x"] = $position[0]; $containerInfo["y"] = $position[1]; $elementInfo = Arr::getVals($elementInfo, array( "srcX" => "x", "srcY" => "y", "srcW" => "w", "srcH" => "h", )); extract($elementInfo); $containerInfo = Arr::getVals($containerInfo, array( "destX" => "x", "destY" => "y", "destW" => "w", "destH" => "h", "color" => "color", )); extract($containerInfo); $prevSrc = $src; $src = isset($color) ? self::create($destW, $destH, $color) : self::create($destW, $destH); return $src !== false ? imagecopyresampled( $src, $prevSrc, $destX, $destY, $srcX, $srcY, $srcW, $srcH, $srcW, $srcH ) : false; } } public static function setBorder(&$src, $borderColor = array(0, 0, 0, 1), $borderSize = 1){ if(!is_resource($src) || !Number::isInt($borderSize) || $borderSize < 1){ return false; } if(!($imageSize = self::getImageResSize($src))) return false; $containerSize = array($borderSize * 2 + $imageSize[0], $borderSize * 2 + $imageSize[1]); return self::crop( $src, array("x" => 0, "y" => 0, "w" => $imageSize[0], "h" => $imageSize[1]), array("x" => $borderSize, "y" => $borderSize, "w" => $containerSize[0], "h" => $containerSize[1], "color" => $borderColor) ); } public static function puzzle($containerInfo, $images){ $params = func_get_args(); if(!Arr::isAvailable($containerInfo, array("w", "h"))) return false; foreach($images as $key => $image){ if(!Arr::isAvailable($image, array("res", "layer_num", "x", "y", "w", "h"))) unset($images[$key]); } if(!$images) return false; Arr::sortByField($images, "layer_num", "DESC"); if(isset($containerInfo["bg_color"])) $dest = self::create($containerInfo["w"], $containerInfo["h"], $containerInfo["bg_color"]); else $dest = self::create($containerInfo["w"], $containerInfo["h"]); foreach($images as $image){ $position = self::calcPosition($image, $containerInfo); $image["x"] = $position[0]; $image["y"] = $position[1]; imagecopyresampled( $dest, $image["res"], $image["x"], $image["y"], 0, 0, $image["w"], $image["h"], $image["w"], $image["h"] ); } return $dest; } }