Php 单色位图的 imagebmp
Php imagebmp for monochrome bitmap
如何实现单色BMP的imagebmp()函数?
我发现很多 24 位位图的实现,但没有关于 1 位位图的实现。
这是一个有效的实现。
我使用了一个 bindec 函数,我可以使用移位运算符进行优化,但我发现字符串填充函数非常简单。
function imagebmp(&$img, $filename = false)
{
$wid = imagesx($img);
$hei = imagesy($img);
$wid_pad = str_pad('', (4-ceil($wid/8) % 4) %4, "[=10=]");
$size = 62 + ( ceil($wid/8) + strlen($wid_pad)) * $hei;
//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(0);
$header['important_colors'] = dword(0);
$header['white'] = chr(255).chr(255).chr(255).chr(0);
$header['black'] = chr(0).chr(0).chr(0).chr(0);
if ($filename)
{
$f = fopen($filename, "wb");
foreach ($header AS $h)
{
fwrite($f, $h);
}
//save pixels
$str="";
for ($y=$hei-1; $y>=0; $y--)
{
$str="";
for ($x=0; $x<$wid; $x++)
{
$rgb = imagecolorat($img, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$gs = (($r*0.299)+($g*0.587)+($b*0.114));
if($gs>150) $color=0;
else $color=1;
$str=$str.$color;
if($x==$wid-1){
$str=str_pad($str, 8, "0");
}
if(strlen($str)==8){
fwrite($f, chr((int)bindec($str)));
$str="";
}
}
fwrite($f, $wid_pad);
}
fclose($f);
}
else
{
foreach ($header AS $h)
{
echo $h;
}
//save pixels
for ($y=$hei-1; $y>=0; $y--)
{
for ($x=0; $x<$wid; $x++)
{
$rgb = imagecolorat($img, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$gs = (($r*0.299)+($g*0.587)+($b*0.114));
if($gs>150) $color=0;
else $color=1;
$str=$str.$color;
if($x==$wid-1){
$str=str_pad($str, 8, "0");
}
if(strlen($str)==8){
echo chr((int)bindec($str));
$str="";
}
}
echo $wid_pad;
}
}
}
function dword($n)
{
return pack("V", $n);
}
function word($n)
{
return pack("v", $n);
}
如何实现单色BMP的imagebmp()函数? 我发现很多 24 位位图的实现,但没有关于 1 位位图的实现。
这是一个有效的实现。 我使用了一个 bindec 函数,我可以使用移位运算符进行优化,但我发现字符串填充函数非常简单。
function imagebmp(&$img, $filename = false)
{
$wid = imagesx($img);
$hei = imagesy($img);
$wid_pad = str_pad('', (4-ceil($wid/8) % 4) %4, "[=10=]");
$size = 62 + ( ceil($wid/8) + strlen($wid_pad)) * $hei;
//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(0);
$header['important_colors'] = dword(0);
$header['white'] = chr(255).chr(255).chr(255).chr(0);
$header['black'] = chr(0).chr(0).chr(0).chr(0);
if ($filename)
{
$f = fopen($filename, "wb");
foreach ($header AS $h)
{
fwrite($f, $h);
}
//save pixels
$str="";
for ($y=$hei-1; $y>=0; $y--)
{
$str="";
for ($x=0; $x<$wid; $x++)
{
$rgb = imagecolorat($img, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$gs = (($r*0.299)+($g*0.587)+($b*0.114));
if($gs>150) $color=0;
else $color=1;
$str=$str.$color;
if($x==$wid-1){
$str=str_pad($str, 8, "0");
}
if(strlen($str)==8){
fwrite($f, chr((int)bindec($str)));
$str="";
}
}
fwrite($f, $wid_pad);
}
fclose($f);
}
else
{
foreach ($header AS $h)
{
echo $h;
}
//save pixels
for ($y=$hei-1; $y>=0; $y--)
{
for ($x=0; $x<$wid; $x++)
{
$rgb = imagecolorat($img, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$gs = (($r*0.299)+($g*0.587)+($b*0.114));
if($gs>150) $color=0;
else $color=1;
$str=$str.$color;
if($x==$wid-1){
$str=str_pad($str, 8, "0");
}
if(strlen($str)==8){
echo chr((int)bindec($str));
$str="";
}
}
echo $wid_pad;
}
}
}
function dword($n)
{
return pack("V", $n);
}
function word($n)
{
return pack("v", $n);
}