class image_model {
function openFile($file) {
$ext=strtolower(preg_replace("/^.+\.(\w+)$/","$1",$file));
switch($ext) {
case 'gif':
return imagecreatefromgif($file);
case 'jpg':
case 'jpeg':
return imagecreatefromjpeg($file);
case 'png':
return imagecreatefrompng($file);
}
return null;
}
function removeBackground($image) {
$im=$image;
if(is_string($im)) {
$im=$this->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];
}
}
?>