openFile($im); } if(!$im) return; $w=imagesx($im); $h=imagesy($im); //print "Image is $w x $h
"; if (!imageistruecolor($im)) { $img1 = imagecreatetruecolor($w,$h); imagecopy($img1,$im,0,0,0,0,$w,$h); $im = $img1; } $out = imageCreateTrueColor($w,$h); $_bgColors=array(); $total=0; for ($x = 0; $x < $w; $x++) { for ($y = 0; $y < $h; $y++) { if(self::distanceFromEdge($x,$y,$w,$h) > 5) continue; $src_pix = self::colorAround($im,$x,$y); $_bgColors[$src_pix]++; $total++; } } $bgColors=array(); foreach($_bgColors as $color => $c) { $rgb=self::RGBToArray($color); $bgColors[]=$rgb; } #print count($_bgColors)." _bgcolors
"; foreach($_bgColors as $color => $c) { $rgb=self::RGBToArray($color); list($diff,$closest)=self::colorDiff($rgb,$bgColors,60,true); if($diff <= 60) { $color=self::arrayToRGB($closest); $_bgColors[$color]+=$c; unset($_bgColors[$color]); } } #print count($_bgColors)." _bgcolors
"; arsort($_bgColors); $sum=0; $bgColors=array(); foreach($_bgColors as $color => $c) { $rgb=self::RGBToArray($color); $sum+=$c; $bgColors[]=$rgb; if($sum/$total >= 0.75 or count($bgColors)>500) break; } #print count($bgColors)." bgcolors
"; #show($bgColors); #exit; $alpha=imagecolorallocatealpha($out, 0,0,0,0); $alphadiff=30; for ($x = 0; $x < $w; $x++) { $seenFG=false; for ($y = 0; $y < $h/2; $y++) { $color=null; if($seenFG) { $src_pix = imagecolorat($im,$x,$y); list($r,$g,$b) = self::RGBToArray($src_pix); $color=imagecolorallocate($out, $r,$g,$b); } else { $src_pix = self::colorAround($im,$x,$y); list($diff,$closest)=self::colorDiff(self::RGBToArray($src_pix),$bgColors,$alphadiff); if($diff <=$alphadiff) { $color=$alpha; } else { if($diff > 90) $seenFG=true; $src_pix = imagecolorat($im,$x,$y); list($r,$g,$b) = self::RGBToArray($src_pix); $a=round(127*min(40,$diff)/40); $color=imagecolorallocatealpha($out, $r,$g,$b,$a); } } imagesetpixel($out, $x, $y, $color); } $seenFG=false; for ($y = $h-1; $y >= $h/2; $y--) { $color=null; if($seenFG) { $src_pix = imagecolorat($im,$x,$y); list($r,$g,$b) = self::RGBToArray($src_pix); $color=imagecolorallocate($out, $r,$g,$b); } else { $src_pix = self::colorAround($im,$x,$y); list($diff,$closest)=self::colorDiff(self::RGBToArray($src_pix),$bgColors,$alphadiff); if($diff <=$alphadiff) { $color=$alpha; } else { if($diff > 90) $seenFG=true; $src_pix = imagecolorat($im,$x,$y); list($r,$g,$b) = self::RGBToArray($src_pix); $a=round(127*min(40,$diff)/40); $color=imagecolorallocatealpha($out, $r,$g,$b,$a); } } imagesetpixel($out, $x, $y, $color); } } return $out; } static function colorDiff($rgb,$rgblist,$stopat=60,$notTheSame=false) { if(!$rgblist) return 0; $diff=99999; $closest=null; foreach($rgblist as $_rgb) { if($notTheSame and $rgb[0]==$_rgb[0] and $rgb[1]==$_rgb[1] and $rgb[2]==$_rgb[2]) continue; $_diff=abs($rgb[0]-$_rgb[0]) + abs($rgb[1]-$_rgb[1]) + abs($rgb[2]-$_rgb[2]); if($_diff < $diff) { $closest=$_rgb; $diff=$_diff; } if($diff<=$stopat) break; } return array($diff,$closest); } static function colorAround($im,$x,$y) { return imagecolorat($im,$x,$y); $col=0; $col += imagecolorat($im,$x,$y); $col += imagecolorat($im,$x-1,$y); $col += imagecolorat($im,$x+1,$y); $col += imagecolorat($im,$x,$y-1); $col += imagecolorat($im,$x,$y+1); return round(3*$col/15); } static function distanceFromEdge($x,$y,$w,$h) { $xdiff=min($x,$w-$x); $ydiff=min($y,$h-$y); return min($xdiff,$ydiff); } static function RGBToArray($rgb) { $a[0] = ($rgb >> 16) & 0xFF; $a[1] = ($rgb >> 8) & 0xFF; $a[2] = $rgb & 0xFF; return $a; } static function arrayToRGB($a) { return ($a[0] << 16) + ($a[1] << 8) + $a[2]; } } ?>