<?php
/*
* changed : 23. may. 03
* author : hide@address.com
* download: http://www.phpclasses.org/
*
* description :
* this class allows you to create and output bmp-images without
* the use of external modules (like GDlib or Imagemagick)
* since the bmp-format is really large (not optimized in any way),
* it's a rather slow way to deal with images.
* if anyone have the time for it, a dump to gif would be much
* appreciated.
*
* disclaimer :
* this piece of code is freely usable by anyone. if it makes your life better,
* remember me in your eveningprayer. if it makes your life worse, try doing it any
* better yourself.
*/
class bmp_image {
var $data;
var $colors;
var $width;
var $height;
function bmp_image($height, $width, $col=0)
{
$this->height = $height;
$this->width = $width;
$this->colors = array();
for ($i=0;$i<256;$i++)
array_push($this->colors, bmp_image::col_from_rgb(255,255-round($i/2),255-$i));
$this->data = array();
for ($n=0;$n<$height;$n++) {
array_push($this->data, array_pad(array(), $width, $col));
}
}
function plot($x, $y, $col)
{
$this->data[$y][$x] = $col;
}
function line($x, $y, $x1 ,$y1, $col=1)
{
$cc = $x;
$cr = $y;
$c = $x1;
$r = $y1;
$dc = 0;$dr = 0;$sc = 0;$sr = 0;$i = 0;$e = 0;
$dc=abs($c-$cc);
$dr=abs($r-$cr);
$sc=$dc==0?0:($c-$cc)/$dc;
$sr=$dr==0?0:($r-$cr)/$dr;
if ($dc>$dr) {
$e=2*$dr-$dc;
for($i=1; $i<=$dc; $i++) {
$this->plot($cr, $cc, $col);
if($e>=0) {
$cr+=$sr;
$e+=-2*$dc;
}
$cc+=$sc;
$e+=2*$dr;
}
} else {
$e=2*$dc-$dr;
for($i=1; $i<=$dr; $i++) {
$this->plot($cr, $cc, $col);
if($e>=0) {
$cc+=$sc;
$e+=-2*$dr;
}
$cr+=$sr;
$e+=2*$dc;
}
}
}
function bmp_dump($filename='image.bmp', $output=true)
{
$size = ($this->width*$this->height*3)+54;
if ($output) {
header('Content-Type: image/bmp');
header('Pragma: no-cache');
header('Content-Length: '.$size);
header('Content-Disposition: inline; filename='.$filename);
}
// Bitmap File Header
$ret = 'BM'; // header (2b)
$ret .= bmp_image::int_to_dword($size); // size of file (4b)
$ret .= bmp_image::int_to_dword(0); // reserved (4b)
$ret .= bmp_image::int_to_dword(54); // byte location in the file which is first byte of IMAGE (4b)
// Bitmap Info Header
$ret .= bmp_image::int_to_dword(40); // Size of BITMAPINFOHEADER (4b)
$ret .= bmp_image::int_to_dword($this->width); // width of bitmap (4b)
$ret .= bmp_image::int_to_dword($this->height); // height of bitmap (4b)
$ret .= bmp_image::int_to_word(1); // biPlanes = 1 (2b)
$ret .= bmp_image::int_to_word(24); // biBitCount = {1 (mono) or 4 (16 clr ) or 8 (256 clr) or 24 (16 Mil)} (2b)
$ret .= bmp_image::int_to_dword(0); // RLE COMPRESSION (4b)
$ret .= bmp_image::int_to_dword(0); // width x height (4b)
$ret .= bmp_image::int_to_dword(0); // biXPelsPerMeter (4b)
$ret .= bmp_image::int_to_dword(0); // biYPelsPerMeter (4b)
$ret .= bmp_image::int_to_dword(0); // Number of palettes used (4b)
$ret .= bmp_image::int_to_dword(0); // Number of important colour (4b)
// image data
for ($x=count($this->data)-1;$x>=0;$x--) {
for ($y=0;$y<count($this->data[$x]);$y++) {
$ret .= $this->colors[$this->data[$x][$y]];
}
}
if ($output) {
echo $ret;
return null;
} else
return $ret;
}
function int_to_dword($n)
{
return chr($n & 255).chr(($n >> 8) & 255).chr(($n >> 16) & 255).chr(($n >> 24) & 255);
}
function int_to_word($n)
{
return chr($n & 255).chr(($n >> 8) & 255);
}
function col_from_rgb($r,$g,$b)
{
return chr($b).chr($g).chr($r);
}
}
?>