/**
* @(#)bmp.php
* PHP version 5.2.3
*
*
* Copyright 2007 SoftRoad. All Rights Reserved.
*
*====================================================================
* 変更履歴
*
* 新規作成 2007 年5月17日 蒋彪
*/
function imagebmp($img, $file = "", $RLE = 0) {
$ColorCount = imagecolorstotal($img);
$Transparent = imagecolortransparent($img);
$IsTransparent = $Transparent != -1;
if ($IsTransparent)
$ColorCount--;
if ($ColorCount == 0) {
$ColorCount = 0;
$BitCount = 24;
};
if (($ColorCount > 0) and ($ColorCount <= 2)) {
$ColorCount = 2;
$BitCount = 1;
};
if (($ColorCount > 2) and ($ColorCount <= 16)) {
$ColorCount = 16;
$BitCount = 4;
};
if (($ColorCount > 16) and ($ColorCount <= 256)) {
$ColorCount = 0;
$BitCount = 8;
};
$Width = imagesx($img);
$Height = imagesy($img);
$Zbytek = (4 - ($Width / (8 / $BitCount)) % 4) % 4;
$palsize = 0; // cid added
if ($BitCount < 24)
$palsize = pow(2, $BitCount) * 4;
$size = (floor($Width / (8 / $BitCount)) + $Zbytek) * $Height +54;
$size += $palsize;
$offset = 54 + $palsize;
// Bitmap File Header
$ret = 'BM'; // header (2b)
$ret .= int_to_dword($size); // size of file (4b)
$ret .= int_to_dword(0); // reserved (4b)
$ret .= int_to_dword($offset); // byte location in the file which is first byte of IMAGE (4b)
// Bitmap Info Header
$ret .= int_to_dword(40); // Size of BITMAPINFOHEADER (4b)
$ret .= int_to_dword($Width); // width of bitmap (4b)
$ret .= int_to_dword($Height); // height of bitmap (4b)
$ret .= int_to_word(1); // biPlanes = 1 (2b)
$ret .= int_to_word($BitCount); // biBitCount = {1 (mono) or 4 (16 clr ) or 8 (256 clr) or 24 (16 Mil)} (2b)
$ret .= int_to_dword($RLE); // RLE COMPRESSION (4b)
$ret .= int_to_dword(0); // width x height (4b)
$ret .= int_to_dword(0); // biXPelsPerMeter (4b)
$ret .= int_to_dword(0); // biYPelsPerMeter (4b)
$ret .= int_to_dword(0); // Number of palettes used (4b)
$ret .= int_to_dword(0); // Number of important colour (4b)
// image data
$CC = $ColorCount;
$sl1 = strlen($ret);
if ($CC == 0)
$CC = 256;
if ($BitCount < 24) {
$ColorTotal = imagecolorstotal($img);
if ($IsTransparent)
$ColorTotal--;
for ($p = 0; $p < $ColorTotal; $p++) {
$color = imagecolorsforindex($img, $p);
$ret .= inttobyte($color["blue"]);
$ret .= inttobyte($color["green"]);
$ret .= inttobyte($color["red"]);
$ret .= inttobyte(0); //RESERVED
};
$CT = $ColorTotal;
for ($p = $ColorTotal; $p < $CC; $p++) {
$ret .= inttobyte(0);
$ret .= inttobyte(0);
$ret .= inttobyte(0);
$ret .= inttobyte(0); //RESERVED
};
};
$retd = ''; // cid added
if ($BitCount <= 8) {
for ($y = $Height -1; $y >= 0; $y--) {
$bWrite = "";
for ($x = 0; $x < $Width; $x++) {
$color = imagecolorat($img, $x, $y);
$bWrite .= decbinx($color, $BitCount);
if (strlen($bWrite) == 8) {
$retd .= inttobyte(bindec($bWrite));
$bWrite = "";
};
};
if ((strlen($bWrite) < 8) and (strlen($bWrite) != 0)) {
$sl = strlen($bWrite);
for ($t = 0; $t < 8 - $sl; $t++)
$sl .= "0";
$retd .= inttobyte(bindec($bWrite));
};
for ($z = 0; $z < $Zbytek; $z++)
$retd .= inttobyte(0);
};
};
if (($RLE == 1) and ($BitCount == 8)) {
for ($t = 0; $t < strlen($retd); $t += 4) {
if ($t != 0)
if (($t) % $Width == 0)
$ret .= chr(0) .
chr(0);
if (($t +5) % $Width == 0) {
$ret .= chr(0) . chr(5) . substr($retd, $t, 5) . chr(0);
$t += 1;
}
if (($t +6) % $Width == 0) {
$ret .= chr(0) . chr(6) . substr($retd, $t, 6);
$t += 2;
} else {
$ret .= chr(0) . chr(4) . substr($retd, $t, 4);
};
};
$ret .= chr(0) . chr(1);
} else {
$ret .= $retd;
};
if ($BitCount == 24) {
$Dopl = ''; // cid added
for ($z = 0; $z < $Zbytek; $z++)
$Dopl .= chr(0);
for ($y = $Height -1; $y >= 0; $y--) {
for ($x = 0; $x < $Width; $x++) {
$color = imagecolorsforindex($img, ImageColorAt($img, $x, $y));
$ret .= chr($color["blue"]) . chr($color["green"]) . chr($color["red"]);
}
$ret .= $Dopl;
};
};
if ($file != "") {
$r = ($f = fopen($file, "w"));
$r = $r and fwrite($f, $ret);
$r = $r and fclose($f);
return $r;
} else {
echo $ret;
};
};
/*
*------------------------------------------------------------
* ImageCreateFromBmp
*------------------------------------------------------------
* - Reads image from a BMP file
*
* Parameters: $file - Target file to load
*
* Returns: Image ID
*/
function imagecreatefrombmp($file) {
global $CurrentBit, $echoMode;
$f = fopen($file, "r");
$Header = fread($f, 2);
if ($Header == "BM") {
$Size = freaddword($f);
$Reserved1 = freadword($f);
$Reserved2 = freadword($f);
$FirstByteOfImage = freaddword($f);
$SizeBITMAPINFOHEADER = freaddword($f);
$Width = freaddword($f);
$Height = freaddword($f);
$biPlanes = freadword($f);
$biBitCount = freadword($f);
$RLECompression = freaddword($f);
$WidthxHeight = freaddword($f);
$biXPelsPerMeter = freaddword($f);
$biYPelsPerMeter = freaddword($f);
$NumberOfPalettesUsed = freaddword($f);
$NumberOfImportantColors = freaddword($f);
if ($biBitCount < 24) {
$img = imagecreate($Width, $Height);
$Colors = pow(2, $biBitCount);
for ($p = 0; $p < $Colors; $p++) {
$B = freadbyte($f);
$G = freadbyte($f);
$R = freadbyte($f);
$Reserved = freadbyte($f);
$Palette[] = imagecolorallocate($img, $R, $G, $B);
};
if ($RLECompression == 0) {
$Zbytek = (4 - ceil(($Width / (8 / $biBitCount))) % 4) % 4;
for ($y = $Height -1; $y >= 0; $y--) {
$CurrentBit = 0;
for ($x = 0; $x < $Width; $x++) {
$C = freadbits($f, $biBitCount);
imagesetpixel($img, $x, $y, $Palette[$C]);
};
if ($CurrentBit != 0) {
freadbyte($f);
};
for ($g = 0; $g < $Zbytek; $g++)
freadbyte($f);
};
};
};
if ($RLECompression == 1) //$BI_RLE8
{
$y = $Height;
$pocetb = 0;
while (true) {
$y--;
$prefix = freadbyte($f);
$suffix = freadbyte($f);
$pocetb += 2;
$echoit = false;
if ($echoit)
echo "Prefix: $prefix Suffix: $suffix
";
if (($prefix == 0) and ($suffix == 1))
break;
if (feof($f))
break;
while (!(($prefix == 0) and ($suffix == 0))) {
if ($prefix == 0) {
$pocet = $suffix;
$Data .= fread($f, $pocet);
$pocetb += $pocet;
if ($pocetb % 2 == 1) {
freadbyte($f);
$pocetb++;
};
};
if ($prefix > 0) {
$pocet = $prefix;
for ($r = 0; $r < $pocet; $r++)
$Data .= chr($suffix);
};
$prefix = freadbyte($f);
$suffix = freadbyte($f);
$pocetb += 2;
if ($echoit)
echo "Prefix: $prefix Suffix: $suffix
";
};
for ($x = 0; $x < strlen($Data); $x++) {
imagesetpixel($img, $x, $y, $Palette[ord($Data[$x])]);
};
$Data = "";
};
};
if ($RLECompression == 2) //$BI_RLE4
{
$y = $Height;
$pocetb = 0;
/*while(!feof($f))
echo freadbyte($f)."_".freadbyte($f)."
";*/
while (true) {
//break;
$y--;
$prefix = freadbyte($f);
$suffix = freadbyte($f);
$pocetb += 2;
$echoit = false;
if ($echoit)
echo "Prefix: $prefix Suffix: $suffix
";
if (($prefix == 0) and ($suffix == 1))
break;
if (feof($f))
break;
while (!(($prefix == 0) and ($suffix == 0))) {
if ($prefix == 0) {
$pocet = $suffix;
$CurrentBit = 0;
for ($h = 0; $h < $pocet; $h++)
$Data .= chr(freadbits($f, 4));
if ($CurrentBit != 0)
freadbits($f, 4);
$pocetb += ceil(($pocet / 2));
if ($pocetb % 2 == 1) {
freadbyte($f);
$pocetb++;
};
};
if ($prefix > 0) {
$pocet = $prefix;
$i = 0;
for ($r = 0; $r < $pocet; $r++) {
if ($i % 2 == 0) {
$Data .= chr($suffix % 16);
} else {
$Data .= chr(floor($suffix / 16));
};
$i++;
};
};
$prefix = freadbyte($f);
$suffix = freadbyte($f);
$pocetb += 2;
if ($echoit)
echo "Prefix: $prefix Suffix: $suffix
";
};
for ($x = 0; $x < strlen($Data); $x++) {
imagesetpixel($img, $x, $y, $Palette[ord($Data[$x])]);
};
$Data = "";
};
};
if ($biBitCount == 24) {
$img = imagecreatetruecolor($Width, $Height);
$Zbytek = $Width % 4;
for ($y = $Height -1; $y >= 0; $y--) {
for ($x = 0; $x < $Width; $x++) {
$B = freadbyte($f);
$G = freadbyte($f);
$R = freadbyte($f);
$color = imagecolorexact($img, $R, $G, $B);
if ($color == -1)
$color = imagecolorallocate($img, $R, $G, $B);
imagesetpixel($img, $x, $y, $color);
}
for ($z = 0; $z < $Zbytek; $z++)
freadbyte($f);
};
};
return $img;
};
fclose($f);
};
/*
* Helping functions:
*-------------------------
*
* freadbyte($file) - reads 1 byte from $file
* freadword($file) - reads 2 bytes (1 word) from $file
* freaddword($file) - reads 4 bytes (1 dword) from $file
* freadlngint($file) - same as freaddword($file)
* decbin8($d) - returns binary string of d zero filled to 8
* RetBits($byte,$start,$len) - returns bits $start->$start+$len from $byte
* freadbits($file,$count) - reads next $count bits from $file
* RGBToHex($R,$G,$B) - convert $R, $G, $B to hex
* int_to_dword($n) - returns 4 byte representation of $n
* int_to_word($n) - returns 2 byte representation of $n
*/
function freadbyte($f) {
return ord(fread($f, 1));
};
function freadword($f) {
$b1 = freadbyte($f);
$b2 = freadbyte($f);
return $b2 * 256 + $b1;
};
function freadlngint($f) {
return freaddword($f);
};
function freaddword($f) {
$b1 = freadword($f);
$b2 = freadword($f);
return $b2 * 65536 + $b1;
};
function RetBits($byte, $start, $len) {
$bin = decbin8($byte);
$r = bindec(substr($bin, $start, $len));
return $r;
};
$CurrentBit = 0;
function freadbits($f, $count) {
global $CurrentBit, $SMode;
$Byte = freadbyte($f);
$LastCBit = $CurrentBit;
$CurrentBit += $count;
if ($CurrentBit == 8) {
$CurrentBit = 0;
} else {
fseek($f, ftell($f) - 1);
};
return RetBits($Byte, $LastCBit, $count);
};
function RGBToHex($Red, $Green, $Blue) {
$hRed = dechex($Red);
if (strlen($hRed) == 1)
$hRed = "0$hRed";
$hGreen = dechex($Green);
if (strlen($hGreen) == 1)
$hGreen = "0$hGreen";
$hBlue = dechex($Blue);
if (strlen($hBlue) == 1)
$hBlue = "0$hBlue";
return ($hRed . $hGreen . $hBlue);
};
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 decbin8($d) {
return decbinx($d, 8);
};
function decbinx($d, $n) {
$bin = decbin($d);
$sbin = strlen($bin);
for ($j = 0; $j < $n - $sbin; $j++)
$bin = "0$bin";
return $bin;
};
function inttobyte($n) {
return chr($n);
};
?>