视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
PHP_Image图形处理类
2025-10-06 14:48:40 责编:小OO
文档


//使用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;

}

}下载本文

显示全文
专题