add image support for xbm, xpm, wbmp, and bmp image formats

This commit is contained in:
Craig Andrews 2010-02-24 22:24:11 -05:00
parent 8914b69d50
commit d72c357750

View File

@ -99,6 +99,10 @@ class ImageFile
if ($info[2] !== IMAGETYPE_GIF && if ($info[2] !== IMAGETYPE_GIF &&
$info[2] !== IMAGETYPE_JPEG && $info[2] !== IMAGETYPE_JPEG &&
$info[2] !== IMAGETYPE_BMP &&
$info[2] !== IMAGETYPE_WBMP &&
$info[2] !== IMAGETYPE_XBM &&
$info[2] !== IMAGETYPE_XPM &&
$info[2] !== IMAGETYPE_PNG) { $info[2] !== IMAGETYPE_PNG) {
@unlink($_FILES[$param]['tmp_name']); @unlink($_FILES[$param]['tmp_name']);
@ -146,6 +150,18 @@ class ImageFile
case IMAGETYPE_PNG: case IMAGETYPE_PNG:
$image_src = imagecreatefrompng($this->filepath); $image_src = imagecreatefrompng($this->filepath);
break; break;
case IMAGETYPE_BMP:
$image_src = imagecreatefrombmp($this->filepath);
break;
case IMAGETYPE_WBMP:
$image_src = imagecreatefromwbmp($this->filepath);
break;
case IMAGETYPE_XBM:
$image_src = imagecreatefromxbm($this->filepath);
break;
case IMAGETYPE_XPM:
$image_src = imagecreatefromxpm($this->filepath);
break;
default: default:
throw new Exception(_('Unknown file type')); throw new Exception(_('Unknown file type'));
return; return;
@ -153,7 +169,7 @@ class ImageFile
$image_dest = imagecreatetruecolor($size, $size); $image_dest = imagecreatetruecolor($size, $size);
if ($this->type == IMAGETYPE_GIF || $this->type == IMAGETYPE_PNG) { if ($this->type == IMAGETYPE_GIF || $this->type == IMAGETYPE_PNG || $this->type == IMAGETYPE_BMP) {
$transparent_idx = imagecolortransparent($image_src); $transparent_idx = imagecolortransparent($image_src);
@ -176,6 +192,24 @@ class ImageFile
imagecopyresampled($image_dest, $image_src, 0, 0, $x, $y, $size, $size, $w, $h); imagecopyresampled($image_dest, $image_src, 0, 0, $x, $y, $size, $size, $w, $h);
if($this->type == IMAGETYPE_BMP) {
//we don't want to save BMP... it's an inefficient, rare, antiquated format
//save png instead
$this->type = IMAGETYPE_PNG;
} else if($this->type == IMAGETYPE_WBMP) {
//we don't want to save WBMP... it's a rare format that we can't guarantee clients will support
//save png instead
$this->type = IMAGETYPE_PNG;
} else if($this->type == IMAGETYPE_XBM) {
//we don't want to save XBM... it's a rare format that we can't guarantee clients will support
//save png instead
$this->type = IMAGETYPE_PNG;
} else if($this->type == IMAGETYPE_XPM) {
//we don't want to save XPM... it's a rare format that we can't guarantee clients will support
//save png instead
$this->type = IMAGETYPE_PNG;
}
$outname = Avatar::filename($this->id, $outname = Avatar::filename($this->id,
image_type_to_extension($this->type), image_type_to_extension($this->type),
$size, $size,
@ -245,4 +279,101 @@ class ImageFile
return $num; return $num;
} }
} }
//PHP doesn't (as of 2/24/2010) have an imagecreatefrombmp so conditionally define one
if(!function_exists('imagecreatefrombmp')){
//taken shamelessly from http://www.php.net/manual/en/function.imagecreatefromwbmp.php#86214
function imagecreatefrombmp($p_sFile)
{
// Load the image into a string
$file = fopen($p_sFile,"rb");
$read = fread($file,10);
while(!feof($file)&&($read<>""))
$read .= fread($file,1024);
$temp = unpack("H*",$read);
$hex = $temp[1];
$header = substr($hex,0,108);
// Process the header
// Structure: http://www.fastgraph.com/help/bmp_header_format.html
if (substr($header,0,4)=="424d")
{
// Cut it in parts of 2 bytes
$header_parts = str_split($header,2);
// Get the width 4 bytes
$width = hexdec($header_parts[19].$header_parts[18]);
// Get the height 4 bytes
$height = hexdec($header_parts[23].$header_parts[22]);
// Unset the header params
unset($header_parts);
}
// Define starting X and Y
$x = 0;
$y = 1;
// Create newimage
$image = imagecreatetruecolor($width,$height);
// Grab the body from the image
$body = substr($hex,108);
// Calculate if padding at the end-line is needed
// Divided by two to keep overview.
// 1 byte = 2 HEX-chars
$body_size = (strlen($body)/2);
$header_size = ($width*$height);
// Use end-line padding? Only when needed
$usePadding = ($body_size>($header_size*3)+4);
// Using a for-loop with index-calculation instaid of str_split to avoid large memory consumption
// Calculate the next DWORD-position in the body
for ($i=0;$i<$body_size;$i+=3)
{
// Calculate line-ending and padding
if ($x>=$width)
{
// If padding needed, ignore image-padding
// Shift i to the ending of the current 32-bit-block
if ($usePadding)
$i += $width%4;
// Reset horizontal position
$x = 0;
// Raise the height-position (bottom-up)
$y++;
// Reached the image-height? Break the for-loop
if ($y>$height)
break;
}
// Calculation of the RGB-pixel (defined as BGR in image-data)
// Define $i_pos as absolute position in the body
$i_pos = $i*2;
$r = hexdec($body[$i_pos+4].$body[$i_pos+5]);
$g = hexdec($body[$i_pos+2].$body[$i_pos+3]);
$b = hexdec($body[$i_pos].$body[$i_pos+1]);
// Calculate and draw the pixel
$color = imagecolorallocate($image,$r,$g,$b);
imagesetpixel($image,$x,$height-$y,$color);
// Raise the horizontal position
$x++;
}
// Unset the body / free the memory
unset($body);
// Return image-object
return $image;
}
}