//使用UTF-8
/**
* Module: Image Class Module v1.2
*
* author: leaf
* email:yuyuyezi@vip.qq.com
* time: 2012-02-16 14:55
* last_modify-time: 2012-04-19 14:47
* copyright: All Free
*
* functions:
* 1.thumb *
* 2.water mark
* 3.cutPart size
* 4.format convert
* 5.cut border *
* 6.gamma(new)
* 7.gaussPart(new)
* 8.gauss (new)
*/
/*
1、本空间源码部分原创,部分为网络分享。原创部分源码可以任意使用,但作者保留个人版权。 2、大多数情况下,代码已经作者有限的检测和调试,但这不代表代码中一定就不包含错误。您可以自己选择将其用于其它用途,但因此造成的任何后果都与作者无责。
3、如果发现错误,或有更好的建议,请先系作者:yuyuyezi@vip.qq.com。(QQ:910657702)
4、转载请注明出处,以便跟踪其它用户的bug提交。举手之劳,方便大家,谢谢合作!
此代码的详细的使用方法及示例,请访问作者空间。http://hi.baidu.com/zhangshe
*/
//import('leaf.image.RGB'); //导入RGB类
//require_once "RGB.class.php";//导入RGB类
define('SAMPLE_DENSITY',30);//像素点采样精度(每个指定像素采样比对一次)数值越大越精细,但处理也会更耗时
define('CM_LEVAL',20);//颜色匹配级别 color match leval(0-255)
define('CMT_LEVAL',0.9);//匹配次数级别 count match leval(0.1-1)
define('RED_INDEX', 0);//颜色索引
define('GREEN_INDEX', 1);//颜色索引
define('BLUE_INDEX', 2);//颜色索引
define('GAUSS_BLOCK_SIZE',100);//Gauss模糊处理块边大小,一次读取块越小,占用内存越小,同时块数会增加
define('SUPORT_MIME',"JPG,PNG,GIF");//支持的文件类型
define('JPEG_SAVE_QUALITY',80);//JPEG图片保存的质量(0-100)
//RGB Class
class RGB{
private $red= 0;//红绿蓝索引
private $green= 0;
private $blue= 0;
/**
* __construct
*
* @param mix $rgb
*/
function __construct($rgb= null){
$args_array=func_get_args();
if(func_num_args() == 1){
$this->setValue($rgb);
}else if(func_num_args() == 3){
$this->setRed($args_array[0]);
$this->setGreen($args_array[1]);
$this->setBlue($args_array[2]);
}
}
/**
* 设置值
*
* @param mix $rgb
*/
function setValue($rgb){
if($rgb == null){
$this->red= 0;
$this->green= 0;
$this->blue= 0;
}else if(is_array($rgb) && count($rgb) >= 3){
if(isset($rgb['red']) && isset($rgb['green']) && isset($rgb['blue'])){
$this->setRed($rgb['red']);
$this->setGreen($rgb['green']);
$this->setBlue($rgb['blue']);
}elseif(isset($rgb[0]) && isset($rgb[1]) && isset($rgb[2])){
$this->setRed($rgb[0]);
$this->setGreen($rgb[1]);
$this->setBlue($rgb[2]);
}else{
exit('unable rgb setValue source');
}
}else if(is_object($rgb) && get_class($rgb) =
= 'RGB'){
$this->setRed($rgb->getRed());
$this->setGreen($rgb->getGreen());
$this->setBlue($rgb->getBlue());
}else{
print_r($rgb);
exit('unable rgb setValue source');
}
}
/**
* __destruct
*
*/
function __destruct(){
//do nothing.
}
/**
* 设置颜色索引
*
* @param int $red
* @return int 返回设置的颜色索引
*/
function setRed($red){
$this->red= abs(intval($red));
if($this->red > 255){
$this->red= 255;
}
return $this->red;
}
/**
* 设置颜色索引
*
* @param int $red
* @return int 返回设置的颜色索引
*/
function setGreen($green){
$this->green= abs(intval($green));
if($this->green >255 ){
$this->green= 255;
}
return $this->red;
}
/**
* 设置颜色索引
*
* @param int $red
* @return int 返回设置的颜色索引
*/
function setBlue($blue){
$this->blue= abs(intval($blue));
if($this->blue >255 ){
$this->blue= 255;
}
return true;
}
/**
* 获取颜色索引
*
* @return int 颜色索引
*/
function getRed(){
return $this->red;
}
/**
* 获取颜色索引
*
* @return int 颜色索引
*/
function getGreen(){
return $this->green;
}
/**
* 获取颜色索引
*
* @return int 颜色索引
*/
function getBlue(){
return $this->blue;
}
/**
* debug
*
*/
function debug(){
$result= array();
$result['red']= $this->red;
$result['green']= $this->green;
$result['blue']= $this->blue;
print_r($result);
}
/**
* 转换灰度模式的 RGB
*
*/
function Gamma(){
$red= $this->red;
$green= $this->green;
$blue= $this->blue;
//灰度计算方法:
//sRGB IEC61966-2.1 [gamma=2.20](Adobe PS目前使用此方法)
//测试纯红色灰度:126
//Gray = (R^2.2 * 0.2126 + G^2.2 * 0.7152 + B^2.2 * 0.0722)^(1/2.2)
$gray_leval = pow((pow($red,2.2) * 0.2126 + pow($green,2.2) * 0.7152 + pow($blue,2.2) * 0.0722),(1/2.2));
//Adobe RGB (1998) [gamma=2.20]
//测试纯红色灰度:146
//Gray = (R^2.2 * 0.2973 + G^2.2 * 0.6274 + B^2.2 * 0.0753)^(1/2.2)
//$gray_leval = pow((pow($red,2.2) * 0.2973 + pow($green,2.2) * 0.6274 + pow($blue,2.2) * 0.0753),(1/2.2));
//Apple RGB [gamma=1.80]
//测试纯红色灰度:116
//Gray = (R^1.8 * 0.2446 + G^1.8 * 0.6720 + B^1.8 * 0.0833)^(1/1.8)
//$gray_leval = pow((pow($red,1.8) * 0.2446 + pow($green,1.8) * 0.6720 + pow($blue,1.8) * 0.0833),(1/1.8));
//ColorMatch RGB [gamma=1.8]
//测试纯红色灰度:124
//Gray = (R^1.8 * 0.2750 + G^1.8 * 0.6581 + B^1.8 * 0.0670)^(1/1.8)
//$gray_leval = pow((pow($red,1.8) * 0.2750 + pow($green,1.8) * 0.6581 + pow($blue,1.8) * 0.0670),(1/1.8));
//KODAK DC Series Digital Camera [gamma=2.2]
//测试纯红色灰度:128
//Gray = (R^2.2 * 0.2229 + G^2.2 * 0.7175 + B^2.2 * 0.0595)^(1/2.2)
//$gray_leval = pow((pow($
red,2.2) * 0.2229 + pow($green,2.2) * 0.7175 + pow($blue,2.2) * 0.0595),(1/2.2));
$this->setRed($gray_leval);
$this->setGreen($gray_leval);
$this->setBlue($gray_leval);
}
/**
* 颜色的模糊匹配
*
* @param mix $rgb
* @param int $leval
* @return boolean 匹配成功返回true,失败返回 false
*/
function fuzzyMatch($rgb, $leval=0){//模糊匹配
$cm_total= 0;
$leval_add= $leval*0.8;
if(is_object($rgb) && get_class($rgb) == 'RGB'){
$red= abs($this->red- $rgb->red);
$green= abs($this->green- $rgb->green);
$blue= abs($this->blue- $rgb->blue);
if($red >$leval)
return false;
else{
$cm_total+= $red;
$cm_total+= $red>$leval_add?$red-$leval_add : 0;
}
if($green >$leval){
return false;
}else{
$cm_total+= $green;
$cm_total+= $green>$leval_add?$green-$leval_add : 0;
}
if($blue >$leval){
return false;
}else{
$cm_total+= $blue;
$cm_total+= $blue>$leval_add?$blue-$leval_add : 0;
}
if($cm_total >($leval *3)){
return false;
}
return true;
}
exit('RGB.fuzzyMatch request a rgb class');
}
}
//Image Class
class Image{
private $image= null;//图形资源句柄
private $width= 0;//图形宽度
private $height= 0;//图形的高度
private $imageType= null;//图形的类型
private $imageMime= null;//图片MIME
private $imageFilePath= null;//图片所在的目录
private $imageFileName= null;//图片名称
/**
* construct
*
* @param string $imageFile 载入的图片路径
*/
function __construct($imageFile= null){
if($imageFile != null){
$this->loadImage($imageFile);
}
}
/**
* 载入图片
*
* @param string $imageFile
* @return boolean 成功返回true,失败返回 false
*/
function loadImage($imageFile){
if(!is_file($imageFile)){
return false;
}
if($this->isLoad()){
$this->close();
}
if(!$image_infor= Image::get_image_infor($imageFile))
return false;
$this->width = $image_infor['width'];
$this->height= $image_infor['height'];
$this->imageMime= $image_infor['mime'];
$pathName= realpath($imageFile);
$this->imageFilePath= str_replace('\\\\', '/', dirname($pathName).'/');
$this->imageFileName= basename($pathName);
$this->imageType= $image_infor['type'];
$image_type_array= explode(',', SUPORT_MIME);
if(!in_array($this->imageType, $image_type_array)){
return false;
}
switch ($this->imageType){
case 'JPG' :
$this->image = imagecreatefromjpeg($imageFile);
break;
case 'PNG':
$this->image = imagecreatefrompng($imageFile);
break;
case 'GIF':
$this->image = imagecreatefromgif($imageFile);
break;
default:
exit("未处理的图片打开方式'{$this->imageType}'");
}
return true;
}
/**
* 保存图片(图片处理之后的保存操作)
*
* @param string $imgRePath 重定向的保
存目录
* @param unknown_type $imgReName 重命名文件
* @return 成功返回 true 失败返回false
*/
function saveImage( $imgRePath= null,$imgReName= null){
$imgName= $this->imageFileName;
$imgPath= $this->imageFilePath;
if($imgReName != null) $imgName= $imgReName;
if($imgRePath != null) $imgPath= $imgRePath;
if(preg_match("/[\\\\/]$/
his->height=$new_height;
return true;
}
/**
* 裁剪指定区域的部分图片
* 如果指定了背景色,则超出的部分以背景色填充(x<0,y<0时,裁剪后的图片左上部也会填充背景色)
* @param int $xpos开始的x坐标
* @param int $ypos 开始的y坐标
* @param int $width 选取的宽度
* @param int $height 选取的高度
* @param RGB $bg_rgb 背景色
* @return boolean 成功返回 true 失败返回 false
*/
function cutImage($xpos,$ypos,$width,$height,$bg_rgb= null){
$dst_xpos=0;
$dst_ypos=0;
if(!$this->isLoad()){//未打开图片
return false;
}
if(!$width || !$height){//未打开图片
return false;
}
if($bg_rgb == null){
if($xpos <0){
$width+= $xpos;
$xpos=0;
}
if($ypos <0){
$height+= $ypos;
$ypos=0;
}
$width_max= $this->getWidth()-$xpos;//最大的宽度
$height_max= $this->getHeight()-$ypos;//最大的高度
$width= $width > $width_max ? $width_max : $width;
$height= $height > $height_max ? $height_max : $height;
if($width <0 ) return false;//x坐标超出了宽度
if($height <0 ) return false;//y坐标超出了高度
$new_image = imagecreatetruecolor($width,$height);
}else{
$rgb= new RGB($bg_rgb);
$new_image = imagecreatetruecolor($width,$height);//直接使用宽高,超出图片的部分补背景颜色
$back_ground = imagecolorallocate($new_image,$rgb->getRed(),$rgb->getGreen(),$rgb->getBlue());
imagefill($new_image,0,0,$back_ground);//使用背景色填充
if($xpos <0){
$width+= $xpos;
$dst_xpos= -$xpos;
$xpos=0;
}
if($ypos <0){
$height+= $ypos;
$dst_ypos= -$ypos;
$ypos=0;
}
$width_max= $this->getWidth()-$xpos;//最大的有效宽度
$height_max= $this->getHeight()-$ypos;//最大的有效高度
$width= $width > $width_max ? $width_max : $width;
$height= $height > $height_max ? $height_max : $height;
if($width <0 ){
imagedestroy($new_image);
return false;//x坐标超出了宽度
}
if($height <0 ){
imagedestroy($new_image);
return false;//y坐标超出了高度
}
}
imagecopyresampled($new_image, $this->image, $dst_xpos,$dst_ypos, $xpos, $ypos, $width, $height, $width, $height);
imagedestroy($this->image);
$this->image= $new_image;
$this->width= $width;
$this->height=$height;
return true;
}
/**
* 输出image图片,此方法不导出
*
* @param string $imgFileName
*/
private function writeImage($imgFileName){
if($imgFileName == null){
ob_end_clean();
header("Content-Type: {$this->imageMime}");
}
switch ($this->imageType){
case 'JPG' :
imagejpeg($this->image,$imgFileName, JPEG_SAVE_QUALITY);
break;
case 'PNG':
imagepng($this->image, $imgFileName);
break;
case 'GIF':
imagegif($this->image, $imgFileName);
break;
//case 'WBMP':
//im
agewbmp($this->image, $imgFileName);
default:
exit("不支持的图片存储格式 '{$this->imageType}'");
}
return true;
}
/**
* 转换图片格式
*
* @param string $newType 新的图片格式(不是所有的都能支持保存)
* @return boolean 成功返回true
*/
function formatConversion($newType){
if(is_integer($newType)){
switch($newType){
case 1: $newType= 'GIF'; break;
case 2: $newType= 'JPG'; break;
case 3: $newType= 'PNG'; break;
case 4: $newType= 'SWF'; break;
case 5: $newType= 'PSD'; break;
case 6: $newType= 'BMP'; break;
case 7: $newType= 'TIFF';break;
case 8: $newType= 'TIFF';break;
case 9: $newType= 'JPC'; break;
case 10: $newType= 'JP2'; break;
case 11: $newType= 'JPX'; break;
case 12: $newType= 'JB2'; break;
case 13: $newType= 'SWC'; break;
case 14: $newType= 'IFF'; break;
case 15: $newType= 'WBMP';break;
case 16: $newType= 'XBM'; break;
default: exit('未知的图片文件存储格式');
}
}
$newType= strtoupper($newType);
$image_type_array= explode(',', SUPORT_MIME);
if(in_array($newType, $image_type_array)){
$this->imageType= $newType;
//同时修改将来保存的默认文件名
$reFileNameArr= explode('.', $this->imageFileName);
if(count($reFileNameArr)>1) array_pop($reFileNameArr);
$this->imageFileName= implode('.', $reFileNameArr).'.'.$this->imageType;
return true;
}
exit("不支持的格式转换存储 {$newType}");
}
/**
* 判断图片是否正确加载
*
* @return boolean 成功加载返回 true,出错返回false
*/
function isLoad(){
if($this->image == null)
return false;
return true;
}
/**
* 获取图片文件的详细信息(该方法公用)
*
* @param string $image_file 图片文件路径
* @return array 成功返回图片详细信息数组,失败返回 null
*/
static function get_image_infor($image_file){
if(!!$arr_image_infor= @getimagesize($image_file)){
$image_infor = &$arr_image_infor;
$image_infor['type_index']= $arr_image_infor[2];
$image_infor['width']= $arr_image_infor[0];
$image_infor['height']= $arr_image_infor[1];
$image_infor['mime']= $arr_image_infor['mime'];
$image_infor['string_size']= $arr_image_infor[3];
switch($arr_image_infor[2]){
case 1: $image_infor['type']= 'GIF'; break;
case 2: $image_infor['type']= 'JPG'; break;
case 3: $image_infor['type']= 'PNG'; break;
case 4: $image_infor['type']= 'SWF'; break;
case 5: $image_infor['type']= 'PSD'; break;
case 6: $image_infor['type']= 'BMP'; break;
case 7: $image_infor['type']= 'TIFF';break;
case 8: $image_infor['type']= 'TIFF';break;
case 9: $image_infor['type']= 'JPC'; break;
case 10: $image_infor['type']= 'JP2'; break;
case 11: $image_infor['type']= 'JPX'; break;
case 12: $image_infor['type']= 'JB2'
; break;
case 13: $image_infor['type']= 'SWC'; break;
case 14: $image_infor['type']= 'IFF'; break;
case 15: $image_infor['type']= 'WBMP';break;
case 16: $image_infor['type']= 'XBM'; break;
default: $image_infor['type']= '';
}
return $image_infor;
}
return null;
}
/**
* 返回正确载入后的图片格式类型
*
* @return string 成功返回图片格式,失败 返回 null
*/
function imageType(){
if($this->isLoad()){
return $this->imageType;
}
return null;
}
/**
* 水印处理方法
*
* @param resource/string $waterImage 打开的水印图片类或文件目录
* @param int $pct 水印深度 0-100
* @return boolean 处理成功返回 true 失败返回false
*/
function waterMark($waterImage,$pct=50){//水印应为透底的gif或png图片
$auto_free= false;//对于字符串传递的 waterImage需要使用后关闭
if(is_string($waterImage)){
$waterImage= new Image($waterImage);
$auto_free= true;
}
if($waterImage instanceof Image){
if($waterImage->isLoad()){
$image_width= $this->getWidth();
$image_heigth= $this->getHeight();
$waterImage_width =$waterImage->getWidth();
$waterImage_height= $waterImage->getHeight();
for($start_x=0;$start_x<$image_width; $start_x+= $waterImage_width){
for($start_y=0;$start_y<$image_heigth; $start_y+= $waterImage_height){
imagecopymerge($this->image,$waterImage->getImage(),$start_x,$start_y,0,0,$waterImage_width,$waterImage_height,$pct);
}
}
if($auto_free){
$waterImage->close();
unset($waterImage);
}
return true;
}//waterMark image file not loaded error
}//'error at waterMark';
return false;
}
/**
* 垂直线条的模糊匹配
*
* @param RGB $rgb匹配颜色
* @param int $xx坐标的一条垂直线
* @param int $cm_leval颜色匹配级别
* @param float $cmt_persent匹配次数级别
* @return boolean成功返回true,失败返回false
*/
private function fuzzyLineMatchH($rgb,$x,$cm_leval=15,$cmt_persent=0.9){
$match_count= 0;
$rgb_bit= new RGB();
$height= $this->getHeight();
for($y=0,$count=0; $y<$height; $y+=SAMPLE_DENSITY,$count++){
$color_index = imagecolorat($this->image, $x, $y);//取得一点的颜色
$color_tran = imagecolorsforindex($this->image, $color_index);
$rgb_bit->setValue($color_tran);
if($rgb->fuzzyMatch($rgb_bit,$cm_leval)){//查找到边缘
$match_count++;
}
}
if(($match_count*1.0/$count)> $cmt_persent){
return true;
}else{
return false;
}
}
/**
* 水平线条的模糊匹配
*
* @param RGB $rgb//匹配的颜色
* @param int $y//以y坐标的水平线
* @param int $cm_leval
* @param float $cmt_persent
* @return 成功返回 true 失败返回 false
*/
private function fuzzyLineMatchV($rgb,$y,$cm_leval=15,$cmt_persent=0.9){
$match_count= 0;
$rgb_
b_bit= new RGB();
for($x=0,$count=0; $x<$this->width; $x+=SAMPLE_DENSITY,$count++){
$color_index = imagecolorat($this->image, $x, $y);//取得一点的颜色
$color_tran = imagecolorsforindex($this->image, $color_index);
$rgb_bit->setValue($color_tran);
if($rgb_bit->fuzzyMatch($rgb,$cm_leval)){//查找到边缘
$match_count++;
}
}
if(($match_count*1.0/$count)> $cmt_persent){
return true;
}else{
return false;
}
}
/**
* 计算垂直线颜色
*
* @param unknown_type $x
* @return RGB 如果y=$x 是一条垂直线,返回线条RGB,否则返回false
*/
private function findLineH($x){
$red=0;$green=0;$blue=0;
$rgb_bits= array();
for($y=0,$count=0; $y< $this->height; $y+=SAMPLE_DENSITY,$count++){
$color_index = imagecolorat($this->image, $x, $y);//取得一点的颜色
$color_tran = imagecolorsforindex($this->image, $color_index);
$red+= $color_tran['red'];
$green+= $color_tran['green'];
$blue+= $color_tran['blue'];
}
$red /= $count;
$green /= $count;
$blue /= $count;
$rgb= new RGB($red,$green,$blue);
if($this->fuzzyLineMatchH($rgb,$x,10,0.9)){
return $rgb;
}else{
return false;
}
}
/**
* 自动计算水平线颜色
*
* @param unknown_type $x
* @return RGB 如果y=$x 是一条垂直线,返回线条RGB,否则返回false
*/
private function findLineV($y){//计算水平线颜色
$red=0;$green=0;$blue=0;
$rgb_bits= array();
for($x=0,$count=0; $x<$this->width; $x+=SAMPLE_DENSITY,$count++){
$color_index = imagecolorat($this->image, $x, $y);//取得一点的颜色
$color_tran = imagecolorsforindex($this->image, $color_index);
$red+= $color_tran['red'];
$green+= $color_tran['green'];
$blue+= $color_tran['blue'];
}
$red /= $count;
$green /= $count;
$blue /= $count;
$rgb= new RGB($red,$green,$blue);
if($this->fuzzyLineMatchV($rgb,$y,10,0.9)){
return $rgb;
}else{
return false;
}
}
/**
* 查找上边框宽度
*
* @param int $cm_leval 颜色匹配级别 0-255,数字越大,匹配越宽松
* @param RGB $rgb 边框颜色
* @param unknown_type $ctm_persent
* @return int 边框宽度
*/
function shearedEdgeU($cm_leval=15,$rgb= null,$ctm_persent=0.9){
if(!$this->isLoad()) return false;
if($rgb == null){
$rgb= $this->findLineV(0);
}else{
$rgb= new RGB($rgb);
}
if($rgb== null) return 0;
$y_end= $this->getHeight();
for($y=0; $y<$y_end; $y++){
if(!$this->fuzzyLineMatchV($rgb,$y,$cm_leval,$ctm_persent)){//查找到边缘
return $y;
}
}
return 0;
}
/**
* 查找左边框宽度
*
* @param int $cm_leval 颜色匹配级别 0-255,数字越大,匹配越宽松
* @param RGB $rgb 边框颜色
* @param unknown_type $ctm_persent
* @return int 边框宽度
*/
function shearedEdgeL($cm_leval=15,$rgb= null,$ctm_persent=0.9){
if(!$this->isLoad()
) return false;
if($rgb == null){
$rgb= $this->findLineH(0);
}else{
$rgb= new RGB($rgb);
}
if($rgb== null) return 0;
$x_end= $this->getWidth();
for($x=0; $x<$x_end; $x++){
if(!$this->fuzzyLineMatchH($rgb,$x,$cm_leval,$ctm_persent)){//查找到边缘
return $x;
}
}
return 0;
}
/**
* 查找下边框宽度
*
* @param int $cm_leval 颜色匹配级别 0-255,数字越大,匹配越宽松
* @param RGB $rgb 边框颜色
* @param unknown_type $ctm_persent
* @return int 边框宽度
*/
function shearedEdgeD($cm_leval=15,$rgb= null,$ctm_persent=0.9){
if(!$this->isLoad()) return false;
if($rgb == null){
$rgb= $this->findLineV($this->getHeight()-1);
}else{
$rgb= new RGB($rgb);
}
if($rgb== null) return 0;
for($y=$this->getHeight() -1; $y>0; $y--){
if(!$this->fuzzyLineMatchV($rgb,$y,$cm_leval,$ctm_persent)){//查找到边缘
return $this->getHeight()- 1- $y;
}
}
return 0;
}
/**
* 查找右边框宽度
*
* @param int $cm_leval 颜色匹配级别 0-255,数字越大,匹配越宽松
* @param RGB $rgb 边框颜色
* @param unknown_type $ctm_persent
* @return int 边框宽度
*/
function shearedEdgeR($cm_leval=15,$rgb= null,$ctm_persent=0.9){
if(!$this->isLoad()) return false;
if($rgb == null){
$rgb= $this->findLineH($this->getWidth()-1);
}else{
$rgb= new RGB($rgb);
}
if($rgb== null) return 0;
for($x=$this->getWidth() -1; $x>=0; $x--){
if(!$this->fuzzyLineMatchH($rgb,$x,$cm_leval,$ctm_persent)){//查找到边缘
return $this->getWidth()-1 -$x;
}
}
return 0;
}
/**
* 查找图片边框,并进行裁剪删去边框操作
*
* @param int $leval 颜色匹配级别
* @param RGB $rgb 手动设置边框颜色
* @return 成功返回true,失败false
*/
function shearedEdge($leval=CM_LEVAL,$rgb= null){
$top=0;//顶部边框尺寸
$left=0;//左部边框尺寸
$botom=0;//底部边框尺寸
$right=0;//右部边框尺寸
/*
$pcmk= true;
$top_pcmk= true;//顶部边框处理标记
$left_pcmk= true;//左部边框处理标记
$botom_pcmk=true;//底部边框处理标记
$right_pcmk=true;//右部边框处理标记
while($pcmk){
$pcmk= false;
if($top_pcmk && $top= $this->shearedEdgeU($leval,$rgb)){
$top_pcmk= false;
$pcmk= true;
}
if($left_pcmk && $left= $this->shearedEdgeL($leval,$rgb)){
$left_pcmk= false;
$pcmk= true;
}
if($botom_pcmk && $botom= $this->shearedEdgeD($leval,$rgb)){
$botom_pcmk= false;
$pcmk= true;
}
if($right_pcmk && $right= $this->shearedEdgeR($leval,$rgb)){
$right_pcmk= false;
$pcmk= true;
}
}
*/
$top= $this->shearedEdgeU($leval,$rgb);//顶部边框尺寸
$left= $this->shearedEdgeL($leval,$rgb);//左部边框尺寸
$botom=$this->shearedEdgeD($leval,$rgb);//底部边框尺寸
$right=$this->shearedEdgeR($le
val,$rgb);//右部边框尺寸
$x= $left;
$y= $top;
$width= $this->getWidth()- $left- $right;
$height= $this->getHeight()- $top- $botom;
return $this->cutImage($x,$y,$width,$height);
}
////////////////////////////////////
/**
* 获取位图表
* @param int $x_pos
* @param int $y_pos
* @param int $width
* @param int $height
* @return boolean|array[][] >
*/
function getBitMap($x_pos, $y_pos, $width, $height){
$img_width= $this->getWidth();//缓存像素内存块
$img_height= $this->getHeight();
$x_pos= intval($x_pos);
$y_pos= intval($y_pos);
if($x_pos < 0 || $x_pos > $img_width || $y_pos < 0 || $y_pos > $img_height) return false;
if($width < 0 || $height < 0) return false;
$width= intval($width+ $x_pos);
$height= intval($height+ $y_pos);
if($width > $img_width){
$width= $img_width;
}
if($height > $img_height){
$height= $img_height;
}
$image_bits= array();
for($x=$x_pos; $x < $width; $x++){
for($y=$y_pos; $y < $height; $y++){
$bit= array();
$pix= imagecolorsforindex($this->image, imagecolorat($this->image, $x, $y));
$bit[0]= $pix['red'];
$bit[1]= $pix['green'];
$bit[2]= $pix['blue'];
$image_bits[$x][$y]= $bit;
}
}
return $image_bits;
}
/**
* 转换灰度模式
*
* @return boolean
*/
function gamma(){
if(!$this->isLoad()){//未打开图片
return false;
}
$rgb_bit= new RGB();
$width= $this->getWidth();
$height= $this->getHeight();
for($x=0; $x<$width; $x++){
for($y=0; $y<$height; $y++){
$pix_cur= imagecolorsforindex($this->image, imagecolorat($this->image, $x, $y));
$rgb_bit->setValue($pix_cur);
$rgb_bit->Gamma();
$color = imagecolorallocate($this->image, $rgb_bit->getRed(), $rgb_bit->getGreen(), $rgb_bit->getBlue());
imagesetpixel($this->image, $x, $y, $color);
}
}
return true;
}
/**
* 高斯模糊区域处理方法
* @param int $nRadius
* @param int $x_pos
* @param int $y_pos
* @param int $width
* @param int $height
* @return boolean
*/
function gaussPart($nRadius, $x_pos, $y_pos, $width, $height){
$nRadius= intval($nRadius);
//$diamet = $nRadius *2 + 1;//采样区域直径,或者方阵的边长
$sigma = $nRadius / 3.0;//正态分布的标准偏差σ
$sigma2 = 2.0 * $sigma * $sigma;//2倍的σ平方,参考N维空间正态分布方程
$nuclear = 0.0;//高斯卷积核
if(!$this->isLoad()){//未打开图片
return false;
}
if($nRadius < 1){//采样区域半径
return false;
}
//计算高斯矩阵
$matrix= array();//高斯矩阵定义
for($x = -$nRadius; $x <= $nRadius; $x++)
for($y = -$nRadius; $y <= $nRadius; $y++){
$result = exp(-($x * $x + $y * $y) / $sigma2);
$nuclear += $result;
$matrix[$x][$y]= $result;
}
//缓存像素内存块
$image_bits= array();
$img_width= $this
->getWidth();//原图片大小
$img_height= $this->getHeight();
//x,y坐标合法性检查
$x_pos= intval($x_pos);
$y_pos= intval($y_pos);
if($x_pos < 0 || $x_pos >= $img_width || $y_pos < 0 || $y_pos >= $img_height) return false;
//处理像素矩阵的宽与高
$width= intval($width);
$height= intval($height);
if($width < 0 || $height < 0 ) return false;
$width+= $x_pos;
$height+= $y_pos;
if($width > $img_width) $width= $img_width;
if( $height > $img_height) $height= $img_height;
//采样缓存图片
$pix_x= $x_pos- $nRadius;//为了使边缘自然,采样缓存区域应大于nRadius像素
$pix_y= $y_pos- $nRadius;
$pix_width= $width+ $nRadius;
$pix_height= $height+ $nRadius;
for($x=$pix_x; $x<$pix_width; $x++)
{
for($y=$pix_y; $y<$pix_height; $y++){
$bit= array();
$x_index= $x;
$y_index= $y;
if($x_index < 0)$x_index= -$x_index;//插入虚拟坐标点处理,以便使边界更自然
if($y_index < 0)$y_index= -$y_index;
$x_index= $x_index% $img_width;//平铺处理边界
$y_index= $y_index% $img_height;
$pix= imagecolorsforindex($this->image, imagecolorat($this->image, $x_index, $y_index));
$bit[0]= $pix['red'];
$bit[1]= $pix['green'];
$bit[2]= $pix['blue'];
$image_bits[$x][$y]= $bit;
}
}
//遍历并处理像素
for($x = $x_pos; $x < $width; $x++){
for($y = $y_pos; $y < $height; $y++){
$red= 0.0;//分析取样区域
$green= 0.0;
$blue= 0.0;
for ($m = -$nRadius; $m <= $nRadius; $m++){
$yy = $y + $m;
for($n = -$nRadius; $n <= $nRadius; $n++){
$xx = $x + $n;
$weight = $matrix[$m][$n] / $nuclear;
$red += $weight * $image_bits[$xx][$yy][0];
$green += $weight * $image_bits[$xx][$yy][1];
$blue += $weight * $image_bits[$xx][$yy][2];
}
}
//保存一个像素处理结果
$red= $red > 255 ? 255: intval($red);
$green= $green > 255 ? 255:intval($green);
$blue= $blue > 255 ? 255: intval($blue);
$new_color = imagecolorallocate($this->image, $red, $green, $blue);
imagesetpixel($this->image, $x, $y, $new_color);
}
}
return true;
}
/**
* 高斯模糊图片分块处理方法(大图使用分块GAUSS_BLOCK_SIZE处理)
* @param int $nRadius
* @return boolean
*/
function gauss($nRadius){
$nRadius= intval($nRadius);
//$diamet = $nRadius *2 + 1;//采样区域直径,或者方阵的边长
$sigma = $nRadius / 3.0;//正态分布的标准偏差σ
$sigma2 = 2.0 * $sigma * $sigma;//2倍的σ平方,参考N维空间正态分布方程
$nuclear = 0.0;//高斯卷积核
if(!$this->isLoad()){//未打开图片
return false;
}
if($nRadius < 1){//采样区域半径
return false;
}
//计算高斯矩阵
$matrix= array();//高斯矩阵定义
for($x = -$nRadius; $x <= $nRadius; $x++){
for($y = -$nRadius; $y <=
$nRadius; $y++){
$result = exp(-($x * $x + $y * $y) / $sigma2);
$nuclear += $result;
$matrix[$x][$y]= $result;
}
}
$width= $this->getWidth();//原图片大小
$height= $this->getHeight();
$block_count_x= ceil($width/GAUSS_BLOCK_SIZE);
$block_count_y= ceil($height/GAUSS_BLOCK_SIZE);
$block_data_buff= array();
for($block_x=0; $block_x < $block_count_x; $block_x++){
for($block_y=0; $block_y < $block_count_y; $block_y++){
$block_data_left= null;
$block_data_top= null;
if(isset($block_data_buff[$block_x - 1][$block_y])){
$block_data_left= &$block_data_buff[$block_x - 1][$block_y];
}
if(isset($block_data_buff[$block_x][$block_y -1])){
$block_data_top= &$block_data_buff[$block_x][$block_y - 1];
}
$block_data_buff[$block_x][$block_y]= $this->getGaussBlockBitmap($block_x, $block_y, $nRadius, $block_data_left, $block_data_top);
$this->gaussBlockProcess($block_x, $block_y, $nRadius, $matrix, $nuclear, $block_data_buff[$block_x][$block_y]);
if($block_x > 0 && $block_y > 0){
unset($block_data_buff[$block_x - 1][$block_y - 1]);
}
if($block_y == $block_count_y-1 && $block_x > 0){
unset($block_data_buff[$block_x- 1][$block_y]);
}
unset($block_data_left);
unset($block_data_top);
}
}
return true;
}
/**
* 高斯模糊:图片位图块选取
* @param int $block_x
* @param int $block_y
* @param int $nRadius
* @param array $block_data_left
* @param array $block_data_top
*/
private function getGaussBlockBitmap($block_x, $block_y, $nRadius, $block_data_left, $block_data_top){
//缓存像素内存块
$image_bits= array();
$img_width= $this->getWidth();//原图片大小
$img_height= $this->getHeight();
//x,y坐标位移
$x_pos= $block_x* GAUSS_BLOCK_SIZE;
$y_pos= $block_y* GAUSS_BLOCK_SIZE;
if($x_pos >= $img_width || $y_pos >= $img_height) return null;
//处理像素矩阵的宽与高
$width= $x_pos+ GAUSS_BLOCK_SIZE;
$height= $y_pos+ GAUSS_BLOCK_SIZE;
if($width > $img_width) $width= $img_width;
if( $height > $img_height) $height= $img_height;
//采样缓存图片
$pix_x= $x_pos- $nRadius;//为了使边缘自然,采样缓存区域应大于nRadius像素
$pix_y= $y_pos- $nRadius;
$pix_width= $width+ $nRadius;
$pix_height= $height+ $nRadius;
//获取像素
if($block_x != 0 /*&& $block_data_left != null*/){
for($x=$pix_x; $x < $pix_x+ $nRadius; $x++){
for($y= $pix_y; $y <$pix_height; $y++){
$image_bits[$x][$y]= $block_data_left[$x][$y];
}
}
$pix_x+= $nRadius;
}
if($block_y != 0 /*&& $block_data_top != null*/){
$a=$pix_y + $nRadius;
for($x=$pix_x; $x<$pix_width; $x++){
for($y= $pix_y; $y <$pix_y + $nRadius; $y++){
$image_bits[$x][$y]= $block_data_top[$x][$y];
}
}
$pix_y+= $nRadius;
}
for($x=$pix_x; $x<$pix_width; $x++)
for($y=$pix_y; $y<$pix_height; $y++){
$bit= array();
$x_index= $x;
$y_index= $y;
if($x_index < 0) $x_index= -$x_index;//插入虚拟坐标点处理,以便使边界更自然
if($y_index < 0) $y_index= -$y_index;
$x_index= $x_index% $img_width;//平铺处理边界
$y_index= $y_index% $img_height;
$pix= imagecolorsforindex($this->image, imagecolorat($this->image, $x_index, $y_index));
$bit[0]= $pix['red'];
$bit[1]= $pix['green'];
$bit[2]= $pix['blue'];
$image_bits[$x][$y]= $bit;
}
}
return $image_bits;
}
/**
* 高斯模糊:图片位图块处理
* @param int $block_x
* @param int $block_y
* @param int $nRadius
* @param array $matrix
* @param double $nuclear
* @param array $image_bits
*/
private function gaussBlockProcess($block_x, $block_y, $nRadius, $matrix, $nuclear, $image_bits){
$img_width= $this->getWidth();//原图片大小
$img_height= $this->getHeight();
$x_pos= $block_x* GAUSS_BLOCK_SIZE;//x,y坐标位移
$y_pos= $block_y* GAUSS_BLOCK_SIZE;
$width= $x_pos+ GAUSS_BLOCK_SIZE;//处理像素矩阵的宽与高
$height= $y_pos+ GAUSS_BLOCK_SIZE;
if($width > $img_width) $width= $img_width;
if( $height > $img_height) $height= $img_height;
for($x = $x_pos; $x < $width; $x++){
for($y = $y_pos; $y < $height; $y++){
$red= 0.0;//分析取样区域
$green= 0.0;
$blue= 0.0;
for ($m = -$nRadius; $m <= $nRadius; $m++){
$yy = $y + $m;
for($n = -$nRadius; $n <= $nRadius; $n++){
$xx = $x + $n;
$weight = $matrix[$m][$n] / $nuclear;
$red += $weight * $image_bits[$xx][$yy][0];
$green += $weight * $image_bits[$xx][$yy][1];
$blue += $weight * $image_bits[$xx][$yy][2];
}
}
//保存一个像素处理结果
$red= $red > 255 ? 255: intval($red);
$green= $green > 255 ? 255:intval($green);
$blue= $blue > 255 ? 255: intval($blue);
$new_color = imagecolorallocate($this->image, $red, $green, $blue);
imagesetpixel($this->image, $x, $y, $new_color);
}
}
return true;
}
}下载本文