基本思路是这样的:
首先将图像每个像素点的灰度值计算出来,并保存在数组中(如果是真彩图,可以用PHP函数转化为调色版图像,这样更方便处理)
然后根据wellner算法,构造出一张表用来存放图像每个像素点之前所有点的灰度值之和
最后对每个像素点进行周边区域平均灰度值对比,从而得出该点是黑色还是白色(二值化)
if (imageistruecolor($res)){ imagetruecolortopalette($res, false, 256);//如果是真彩色图象,将真彩色图像转换为调色板图像 } $imgHeight = imagesy($res); $imgWidth = imagesx($res); $grayTable = array();//用于存储图像每个像素点的灰度值。 for($y=0; $y<$imgHeight; $y++){ for($x=0; $x<$imgWidth; $x++){ //获得当前像素点颜色索引值 $colorIndex = imagecolorat($res, $x, $y); //通过颜色索引值获得颜色的RGB数组表示形式 $rgb = imagecolorsforindex($res, $colorIndex); //计算该点的灰度值 $gray = round(0.299 * $rgb['red'] + 0.587 * $rgb['green'] + 0.114 * $rgb['blue']); $grayTable[$x][$y] = $gray; } } $sumColorTable = array(); //颜色求和表 for($y=0; $y<$imgHeight; ++$y){ for($x=0; $x<$imgWidth; ++$x){ if($x==0 && $y==0){ $sumColorTable[$x][$y] = $grayTable[$x][$y]; }else if($y==0 && $x>0){ //第一行的像素灰度和 $sumColorTable[$x][$y] = $sumColorTable[$x-1][$y] + $grayTable[$x][$y]; }else if($x==0 && $y>0){ //第一列的像素灰度和 $sumColorTable[$x][$y] = $sumColorTable[$x][$y-1] + $grayTable[$x][$y]; }else{ $sumColorTable[$x][$y] = $sumColorTable[$x-1][$y] + $sumColorTable[$x][$y-1] - $sumColorTable[$x-1][$y-1] + $grayTable[$x][$y]; } } } $_S = intval($imgWidth / 8); $_T = 15; $ss = intval($_S/2); $imgData = array(); for($y=0; $y<$imgHeight; ++$y){ for($x=0; $x<$imgWidth; ++$x){ $x1 = $x-$ss; $y1 = $y-$ss; $x2 = $x+$ss; $y2 = $y+$ss; if($x1<0) $x1=0; if($y1<0) $y1=0; if($x2>($imgWidth-1)) $x2 = $imgWidth-1; if($y2>($imgHeight-1)) $y2 = $imgHeight-1; if($x1==0 && $y1==0){ $crossArea = 0; $upArea = 0; $leftArea = 0; }else if($y1==0 && $x1>0){ $crossArea = 0; $upArea = 0; $leftArea = $sumColorTable[$x1-1][$y1]; }else if($x1==0 && $y1>0){ $crossArea = 0; $upArea = $sumColorTable[$x1][$y1-1]; $leftArea = 0; }else { $crossArea = $sumColorTable[$x1-1][$y1-1]; $upArea = $sumColorTable[$x2][$y1-1]; $leftArea = $sumColorTable[$x1-1][$y2]; } $D = $sumColorTable[$x2][$y2]; $average = ($D-$upArea-$leftArea+$crossArea)/(($y2-$y1+1)*($x2-$x1+1)); $grayColor = $grayTable[$x][$y]; $colorIndex = imagecolorat($res, $x, $y); if($grayColor<($average*(100-$_T)/100)){ imagecolorset($res, $colorIndex, 0, 0, 0); $imgData[$y][$x] = 1; }else{ $imgData[$y][$x] = 0; imagecolorset($res, $colorIndex, 255, 255, 255); } } } imagejpeg($res,time().'_demo.jpeg');//保存图片