This is an example of black-and-white imagebmp() implementation.
<?php
function imagebwbmp($image, $to = null, $threshold = 0.5)
{
if (func_num_args() < 1) {
$fmt = "imagebwbmp() expects a least 1 parameters, %d given";
trigger_error(sprintf($fmt, func_num_args()), E_USER_WARNING);
return;
}
if (!is_resource($image)) {
$fmt = "imagebwbmp() expects parameter 1 to be resource, %s given";
trigger_error(sprintf($fmt, gettype($image)), E_USER_WARNING);
return;
}
if (!is_numeric($threshold)) {
$fmt = "imagebwbmp() expects parameter 3 to be float, %s given";
trigger_error(sprintf($fmt, gettype($threshold)), E_USER_WARNING);
return;
}
if (get_resource_type($image) !== 'gd') {
$msg = "imagebwbmp(): supplied resource is not a valid gd resource";
trigger_error($msg, E_USER_WARNING);
return false;
}
switch (true) {
case $to === null:
break;
case is_resource($to) && get_resource_type($to) === 'stream':
case is_string($to) && $to = fopen($to, 'wb'):
if (preg_match('/[waxc+]/', stream_get_meta_data($to)['mode'])) {
break;
}
default:
$msg = "imagebwbmp(): Invalid 2nd parameter, it must a writable filename or a writable stream";
trigger_error($msg, E_USER_WARNING);
return false;
}
if ($to === null) {
$to = fopen('php://output', 'wb');
}
$biWidth = imagesx($image);
$biHeight = imagesy($image);
$biSizeImage = ((int)ceil($biWidth / 32) * 32 / 8 * $biHeight);
$bfOffBits = 54 + 4 * 2; $bfSize = $bfOffBits + $biSizeImage;
fwrite($to, 'BM');
fwrite($to, pack('VvvV', $bfSize, 0, 0, $bfOffBits));
fwrite($to, pack('VVVvvVVVVVV', 40, $biWidth, $biHeight, 1, 1, 0, $biSizeImage, 0, 0, 0, 0));
fwrite($to, "\xff\xff\xff\x00"); fwrite($to, "\x00\x00\x00\x00"); for ($y = $biHeight - 1; $y >= 0; --$y) {
$byte = 0;
for ($x = 0; $x < $biWidth; ++$x) {
$rgb = imagecolorsforindex($image, imagecolorat($image, $x, $y));
$value = (0.299 * $rgb['red'] + 0.587 * $rgb['green'] + 0.114 * $rgb['blue']) / 0xff;
$color = (int)($value > $threshold);
$byte = ($byte << 1) | $color;
if ($x % 8 === 7) {
fwrite($to, pack('C', $byte));
$byte = 0;
}
}
if ($x % 8) {
fwrite($to, pack('C', $byte << (8 - $x % 8)));
}
if ($x % 32) {
fwrite($to, str_repeat("\x00", (int)((32 - $x % 32) / 8)));
}
}
return true;
}
?>