Php imagebmp для монохромного растрового изображения

0

Как реализовать функцию imagebmp() для монохромного BMP? Я нашел много реализаций для 24-битного растрового изображения, но ничего около 1 бит растрового изображения.

Теги:
bitmap
gd2

1 ответ

0
Лучший ответ

Это рабочий процесс. Я использовал функцию bindec, меня можно оптимизировать с помощью операторов сдвига, но я нашел очень легкую функцию заполнения строки.

function imagebmp(&$img, $filename = false)
{
    $wid = imagesx($img);
    $hei = imagesy($img);
    $wid_pad = str_pad('', (4-ceil($wid/8) % 4) %4, "\0");

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню