Load and save Bmp in PHP: imagecreatefrombmp + imagebmp

If you want to open or create 24bit BMP images with PHP- just grab my simple library.

Update (02.07.2010): for newer version please scroll down.

You can use this the same way as imagepng, imagepng:


include 'Bmp.php';

header('Content-type: image/bmp');
$im = imagecreatefrompng('test.png');
imagebmp($im);

Or like imagecreatefromjpeg:


$im = imagecreatefrombmp('test.bmp');
imagepng($im);

It can also be used as a class:

header('Content-type: image/bmp');
$im = imagecreatefrompng('test.png');
Bmp::imagebmp($im); 

Or:

header('Content-type: image/png');
$im = Bmp::imagecreatefrombmp('test.bmp');
imagepng($im);

Version 1.1:

This entry was posted on Friday, February 19th, 2010 at 10:53 pm and is filed under PHP. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

13 Responses to “Load and save Bmp in PHP: imagecreatefrombmp + imagebmp”

  1. Hard Says:

    Hello! This class is great! Do you have class like this but doing convertion from gif to bmp (without using additional libraries)?

  2. admin Says:

    Here’s an example to convert GIF to BMP. PHP can load GIFs by itself, so you just need my class to save as BMP.

    //load GIF
    $im = imagecreatefromgif(‘in.gif’);

    //Convert to 24bit
    $w = imagesx($im);
    $h = imagesy($im);
    $im2 = imagecreatetruecolor($w, $h);
    imagecopy($im2, $im);

    //Save as BMP
    imagebmp($im2, ‘out.bmp’);

  3. Terry Says:

    Hi

    I’ve been asked to generate a graph in Excel the only way I could see to do this was to use the GD libary to create an image and then import this into Excel.

    This was then made more complicated because I can only import a BMP into Excel, which is when I found your class. Which is great by the way. Unfortunately something doesn’t quite work as the image is created but it will not import.

    If I open the image in paint and then import it into Excel it work’s.

    Any Idea’s??

  4. admin Says:

    Not sure if this will help, but I updated the class to fix a small bug (thanks Alexander uu2373 for pointing this out). Please check if this helps.

  5. Evhen Molochnyuk Says:

    How I cah check that bmp have 24bit?

  6. admin Says:

    Try to load the file using imagecreatefrombmp(). If the image is not 24bit BMP you will get an error.

    You can also use this code:

    function isBmp24b($filename)
    {
    $f = fopen($filename, “rb”);

    //read header
    $header = fread($f, 54);
    $header = unpack(‘c2identifier/Vfile_size/Vreserved/Vbitmap_data/Vheader_size/’ .
    ‘Vwidth/Vheight/vplanes/vbits_per_pixel/Vcompression/Vdata_size/’.
    ‘Vh_resolution/Vv_resolution/Vcolors/Vimportant_colors’, $header);

    if ($header['identifier1'] != 66 or $header['identifier2'] != 77)
    {
    return false;
    }

    return $header['bits_per_pixel'];
    }

  7. SDemonUA Says:

    Hello,

    2Terry: I’m also use this class for pre-saving image in bmp format to insert it in Excel file.

    For me it works with :
    $size= 54+4*ceil($wid*24/32.0)*$hei;
    Old is :
    //$size = 54 + ($wid + $wid_pad) * $hei * 4; //fixed

  8. Yehonatan Says:

    Thank you its great!

  9. Mad Rog Says:

    Hi,

    I updated the function ‘ImageCreateFromBMP’

    Found here: http://php.net/manual/en/function.imagecreate.php

    and renamed to ‘imagecreatefrombmp’ and now it works with all BMPs not just 24 bit ;-)

    /*********************************************/
    /* Fonction: ImageCreateFromBMP */
    /* Author: DHKold */
    /* Contact: admin@dhkold.com */
    /* Date: The 15th of June 2005 */
    /* Version: 2.0B */
    /*********************************************/
    function imagecreatefrombmp($filename)
    {
    //Ouverture du fichier en mode binaire
    if (! $f1 = fopen($filename,”rb”)) return FALSE;

    //1 : Chargement des ent�tes FICHIER
    $FILE = unpack(“vfile_type/Vfile_size/Vreserved/Vbitmap_offset”, fread($f1,14));
    if ($FILE['file_type'] != 19778) return FALSE;

    //2 : Chargement des ent�tes BMP
    $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;

    //3 : Chargement des couleurs de la palette
    $PALETTE = array();
    if ($BMP['colors'] = 0)
    {
    $X=0;
    while ($X > 4) ; else $COLOR[1] = ($COLOR[1] & 0×0F);
    $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] & 0×40)>>6;
    elseif (($P*8)%8 == 2) $COLOR[1] = ($COLOR[1] & 0×20)>>5;
    elseif (($P*8)%8 == 3) $COLOR[1] = ($COLOR[1] & 0×10)>>4;
    elseif (($P*8)%8 == 4) $COLOR[1] = ($COLOR[1] & 0×8)>>3;
    elseif (($P*8)%8 == 5) $COLOR[1] = ($COLOR[1] & 0×4)>>2;
    elseif (($P*8)%8 == 6) $COLOR[1] = ($COLOR[1] & 0×2)>>1;
    elseif (($P*8)%8 == 7) $COLOR[1] = ($COLOR[1] & 0×1);
    $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'];
    }

    //Fermeture du fichier
    fclose($f1);

    return $res;
    }

  10. HPS Says:

    Thanks! Just what I needed!

    -HP

  11. Mns Says:

    Hi,
    This is great code.
    I was wondering if i can reduce size of generated image. Its generated at 595KB, which is very big compared to its PNG version which is hardly 50-70KB.
    Thanks.

  12. admin Says:

    It is possible to use RLE compression with BMP files but such files are very rare and many BMP reading programs do not support it. Even with RLE compression BMP files are much bigger than PNG.
    So if you want to use BMP it is better to use it without compression. And if you want something small- try PNG, GIF, JPG or TGA.

  13. Felix Says:

    This adds a function to generate 1-bit bmp-images, how they are often used for monochrome lcd displays in devices (I left out the part for files, no harm to add it yourself).

    Thanks for the code, it was a great help to figure out how to go on.

    Felix

    – code –

    function imageBWbmp(&$img, $filename = false)
    {
    $wid = imagesx($img);
    $hei = imagesy($img);
    $wid_pad = str_pad(”, $wid % 4, “”);

    $size = 62 + ($wid + $wid_pad) * $hei * 3 ; //fixed

    //prepare & save header
    $header['identifier']= ‘BM’;
    $header['file_size'] = dword($size);
    $header['reserved'] = dword(0);
    $header['bitmap_data'] = dword(62);
    $header['header_size'] = dword(40);
    $header['width'] = dword($wid);
    $header['height'] = dword($hei);
    $header['planes'] = word(1);
    $header['bits_per_pixel'] = word(1);
    $header['compression'] = dword(0);
    $header['data_size'] = dword(0);
    $header['h_resolution'] = dword(0);
    $header['v_resolution'] = dword(0);
    $header['colors'] = dword(2);
    $header['important_colors'] = dword(2);
    $header['color1'] = dword(hexdec(“#00ffffff”));
    $header['color2'] = dword(hexdec(“#00000000″));

    foreach ($header AS $h){
    echo $h;
    }

    //save pixels
    $byte = “”;
    for ($y=$hei-1; $y>=0; $y–){
    for ($x=0; $x<$wid; $x++){
    if(imagecolorat($img, $x, $y) == $header['color1']){
    $byte .= "1";
    }else{
    $byte .= "0";
    }
    if(strlen($byte) == 8){
    echo chr(bindec($byte));
    $byte = "";
    }
    }
    echo $wid_pad;
    }
    }

Leave a Reply

 
TopOfBlogs Web Development & Design Blogs