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);
}