Convert raster image files to JPEG using the GD library in PHP

I am trying to find a way to convert bitmap files to JPEG using the GD library in PHP.

I tried many implementations but nothing works. I tried to tell my client that they should not use Bitmap files, but he insists and, frankly, is not computer savvy enough to convert them to JPG on their own.

I cannot use ImageMagick on this server, and I need a clean GD solution. Thank you in advance for any help.

EDIT:

The bitmaps used are 16-bit, and that is where the problem arises.

I have this function that I have work .... kinda:

function ImageCreateFromBMP($filename) {
    if (! $f1 = fopen($filename,"rb")) return FALSE;

    $FILE = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1,14));
    if ($FILE['file_type'] != 19778) return FALSE;

    $BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'.
        '/Vcompression/Vsize_bitmap/Vhoriz_resolution'.
        '/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1,40));
    $BMP['colors'] = pow(2,$BMP['bits_per_pixel']);

    if ($BMP['size_bitmap'] == 0) $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset'];
    $BMP['bytes_per_pixel'] = $BMP['bits_per_pixel']/8;
    $BMP['bytes_per_pixel2'] = ceil($BMP['bytes_per_pixel']);
    $BMP['decal'] = ($BMP['width']*$BMP['bytes_per_pixel']/4);
    $BMP['decal'] -= floor($BMP['width']*$BMP['bytes_per_pixel']/4);
    $BMP['decal'] = 4-(4*$BMP['decal']);
    if ($BMP['decal'] == 4) $BMP['decal'] = 0;

    $PALETTE = array();
    if ($BMP['colors'] < 16777216 && $BMP['colors'] != 65536) {
        $PALETTE = unpack('V'.$BMP['colors'], fread($f1,$BMP['colors']*4));
    }

    $IMG = fread($f1,$BMP['size_bitmap']);
    $VIDE = chr(0);

    $res = imagecreatetruecolor($BMP['width'],$BMP['height']);
    $P = 0;
    $Y = $BMP['height']-1;
    while ($Y >= 0) {
        $X=0;
        while ($X < $BMP['width']) {
            if ($BMP['bits_per_pixel'] == 24)
                $COLOR = unpack("V",substr($IMG,$P,3).$VIDE);
            elseif ($BMP['bits_per_pixel'] == 16) {
                $COLOR = unpack("v",substr($IMG,$P,2));
                $blue  = ($COLOR[1] & 0x001f) << 3;
                $green = ($COLOR[1] & 0x07e0) >> 3;
                $red   = ($COLOR[1] & 0xf800) >> 8;
                $COLOR[1] = $red * 65536 + $green * 256 + $blue;
            }
            elseif ($BMP['bits_per_pixel'] == 8) {
                $COLOR = unpack("n",$VIDE.substr($IMG,$P,1));
                $COLOR[1] = $PALETTE[$COLOR[1]+1];
            }
            elseif ($BMP['bits_per_pixel'] == 4) {
                $COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
                if (($P*2)%2 == 0) $COLOR[1] = ($COLOR[1] >> 4) ; else $COLOR[1] = ($COLOR[1] & 0x0F);
                $COLOR[1] = $PALETTE[$COLOR[1]+1];
            }
            elseif ($BMP['bits_per_pixel'] == 1) {
                $COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
                if     (($P*8)%8 == 0) $COLOR[1] =  $COLOR[1]        >>7;
                elseif (($P*8)%8 == 1) $COLOR[1] = ($COLOR[1] & 0x40)>>6;
                elseif (($P*8)%8 == 2) $COLOR[1] = ($COLOR[1] & 0x20)>>5;
                elseif (($P*8)%8 == 3) $COLOR[1] = ($COLOR[1] & 0x10)>>4;
                elseif (($P*8)%8 == 4) $COLOR[1] = ($COLOR[1] & 0x8)>>3;
                elseif (($P*8)%8 == 5) $COLOR[1] = ($COLOR[1] & 0x4)>>2;
                elseif (($P*8)%8 == 6) $COLOR[1] = ($COLOR[1] & 0x2)>>1;
                elseif (($P*8)%8 == 7) $COLOR[1] = ($COLOR[1] & 0x1);
                $COLOR[1] = $PALETTE[$COLOR[1]+1];
            }
            else
                return FALSE;

            imagesetpixel($res,$X,$Y,$COLOR[1]);

            $X++;
            $P += $BMP['bytes_per_pixel'];
        }
        $Y--;
        $P+=$BMP['decal'];
    }

    fclose($f1);
    return $res;
}

The resulting image is as follows:

Uploaded image

, , . . ? 16- else-if.

.

+5
4

:

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

, 16- 32-. , , , , 16- ( 16-) (biClrUsed).

, ;)

2015 : DOMPDF . 4- 8-, 16- 565-.

+10

imagejpeg?

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

imagejpeg() JPEG .

BMP GD, here, .

EDIT: 16- , , . , , , - . , 5 R B, 6 G BGR (, , ):

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";
}

, ( , 0..255), , 5-6-5 - (, , ).

0

GD BMP , userland imagecreatefrombmp().

, , .

0

:

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

This will take any format that GD can handle as input and output the jpeg file. I don’t know which version of GD you are using, but my .bmp pen is excellent, as well as the version we used in the previous company I worked for. (on Mac OS X 10.6 and CentOS 5 respectively)

edit : forgot imagedestroy! Uch!

0
source

All Articles