A: 

How about the imagejpeg function?

bool imagejpeg ( resource $image [, string $filename [, int $quality ]] )

imagejpeg() creates a JPEG file from the given image .

For help to support BMP format in GD, have a look here, for example.

EDIT: This doesn't support 16 bit images which is correct as the original bitmap specification doesn't support it. In your case, please find out which bit pattern is used to code the color value. I assume it's 5 bits for R and B, 6 bits for G and the order is BGR in this solution (please insert into the code I linked to above):

else if ($bits == 16) {
$gd_scan_line = "";
$j = 0;
while($j < $scan_line_size) {
$byte1 = $scan_line{$j++};
$byte2 = $scan_line{$j++};
$b = chr($byte1 >> 3) * (255 / 31); 
$g = (chr($byte1 & 0x07) + chr($byte2 >> 5)) * (255 / 63);
$r = chr($byte2 & 0x1F) * (255 / 31);
$gd_scan_line .= "\x00$r$g$b";
}

Note that I didn't test this code (specifically, I'm not sure about that scaling to 0..255) and it will only work if 5-6-5 bit pattern has been used (well, it will work with others, too, but the colors will be wrong).

schnaader
Thank you for a quick reply but I keep running into the same problem. The bitmap files that my client is using are 16-bit bitmap files. EVERY implementation that I have found (including the one you have shown) account for 24-bit, 8-bit, 4-bit and 1-bit bitmaps.
Daniel P
Thank you again. I tried this solution. The resulting file that was returned was a solid black image with horizontal green lines spaced equally apart the entire length of the image.
Daniel P
A: 

While GD does not support BMP natively, a little big of googling provides a few userland implementations of a imagecreatefrombmp() function.

I haven't tried them, but I'm confident at least one of them will work for you.

timdev
Thanks again. I have tried them all. Again when I do some testing I find out the the bitmaps that are being submitted are 16-bit files. 16-bit images are not accounted for in any of these implementations.
Daniel P
A: 

Off the top of my head:

function convert_to_jpeg( $input_path, $output_path )
{
    $image = imagecreatefromstring(file_get_contents($input_path));
    imagejpeg($image, $output_path);
    imagedestroy($image);
}

That'll take any format GD can handle as input, and output a jpeg file. I don't know what version of GD you folks are using, but mine handles .bmp perfectly and so did the version we used at the previous company I worked for. (on Mac OS X 10.6 and CentOS 5 respectively)

edit: forgot imagedestroy! ouch!

Kris
Let's hope that works for 16-bit BMP files, too... would be the quickest and most elegant solution.
schnaader
Thank you for your help. I gave this a try and got this error:imagecreatefromstring() [function.imagecreatefromstring]: Data is not in a recognized format.This is probably due to the darn 16-bit bitmaps that my client is using.
Daniel P
I don't think I ever ran into a 16bit image, but it seems to work fine for 24bits, and even RLE encoded images.
Kris
A: 

-> schnaader

Did you found a solution?

I've found in the php.net comments a functional 16 Bit function. But I have to include some bug fixes.

This is my result so far:

if ($bmp['colors'] < 16777216) {
 if (!($palette = @unpack('V' . $bmp['colors'], fread($fh, $bmp['colors'] * 4)))) {
  // no palette found: rewind
  $palette = array();
  fseek($fh, 54);
 }
}
...
switch ($bmp['bits_per_pixel']) {
...
case 16:
 // some have palette
 if ($palette) {
  $color = @unpack('n', substr($img, $p, 2));
  if (!$color) {
   break;
  }
  $color[1] = $palette[ $color[1] + 1 ];
 }
 else {
  $color = @unpack('v', substr($img, $p, 2));
  if (!$color) {
   break;
  }
  $color[1] = (($color[1] & 0xf800) >> 8) * 65536 + (($color[1] & 0x07e0) >> 3) * 256 + (($color[1] & 0x001f) << 3);
 }
 break;

This works with images, that doesn't have a palette. With $palette:

maxrev.de/img/cache/crx21271442365.jpg

Without (unset $palette):

maxrev.de/img/cache/crx21271442268.jpg

Afterwards I've tested the other function with your proposal. As Daniel said it doesn't work. This:

case 16:
 $gd_scan_line = '';
 $j = 0;
 while ($j < $scan_line_size) {
  $byte1 = $scan_line{$j++};
  $byte2 = $scan_line{$j++};
/*
  $b = chr($byte1 >> 3) * (255 / 31);
  $g = (chr($byte1 & 0x07) + chr($byte2 >> 5)) * (255 / 63);
  $r = chr($byte2 & 0x1F) * (255 / 31);
*/
  $gd_scan_line .= $byte2;
 }

results (maybe it helps ^^):

maxrev.de/img/cache/crx21271442644.jpg

mgutt
+1  A: 

Ok I finished the function:

http://www.programmierer-forum.de/function-imagecreatefrombmp-welche-variante-laeuft-t143137.htm

Now it supports 16- and 32-bit as well. Plus it contains some bugfixes regarding missing filesize, negative color palettes, error output, additional 16-bit mask header (this was the main problem on 16-bit) and reduced color palette (biClrUsed).

Hope you like it ;)

mgutt