写入正确的位图文件结果

Writing correct bitmap file results

故事:

I have been creating a font renderer for directx9 to draw text, The actual problem got caused by another problem, I was wondering why the texture didnt draw anything (my wrong bitmap), so i tried to copy the bitmap into a file and realized the current problem. yay

问题:

What exactly am i doing wrong? I mean, i just simply copy my CURRENT pixel array in my bitmap wrapper to a file with some other content ( the bitmap infos ), i have seen in an hex editor that there are colors after the bitmap headers.

图片:

This is the result of the bitmap which i have written to the filesystem

代码:

CFont::DrawGlyphToBitmap

This code does copy from a bitmap of an freetype glyph ( which have by the way a pixel format of FT_PIXEL_MODE_BGRA ) to the font bitmap wrapper class instance

void CFont::DrawGlyphToBitmap ( unsigned char * buffer, int rows, int pitch,     int destx, int desty, int format )
{
    CColor color = CColor ( 0 );


    for ( int row = 0; row < rows; row++ )
    {
        int x = 0;
        for ( int left = 0; left < pitch * 3; left += 3,x++ )
        {
            int y = row;
            unsigned char* cursor = &buffer [ ( row*pitch ) + left ];
            color.SetAlphab ( 255 );
            color.SetBlueb ( cursor [ 0 ] );
            color.SetGreenb ( cursor [ 1 ] );
            color.SetRedb ( cursor [ 2 ] );
            m_pBitmap->SetPixelColor ( color, destx + x, desty + y );
        }
    }
}

CBitmap::SetPixelColor

This code does set a single "pixel" / color in its local pixel storage.

void CBitmap::SetPixelColor ( const CColor & color, int left, int top )
{
    unsigned char* cursor = &m_pBuffer [ ( m_iPitch * top ) + ( left *     bytes_per_px ) ];
    cursor [ px_red ] = color.GetRedb ( );
    cursor [ px_green ] = color.GetGreenb ( );
    cursor [ px_blue ] = color.GetBlueb ( );
    if ( px_alpha != 0xFFFFFFFF )
        cursor [ px_alpha ] = color.GetAlphab ( );
}

CBitmap::保存

Heres a outcut of the function which writes the bitmap to the file system, it does shows how i initialize the bitmap info container ( file header & "dib" header )

void CBitmap::Save ( const std::wstring & path )
{

    BITMAPFILEHEADER bitmap_header;
    BITMAPV5HEADER bitmap_info;

    memset ( &bitmap_header, 0, sizeof ( BITMAPFILEHEADER ) );
    memset ( &bitmap_info, 0, /**/sizeof ( BITMAPV5HEADER ) );

    bitmap_header.bfType = 'B' + ( 'M' << 8 );//0x424D;
    bitmap_header.bfSize = bitmap_header.bfOffBits + ( m_iRows * m_iPitch ) * 3;
    bitmap_header.bfOffBits = sizeof ( BITMAPFILEHEADER ) + sizeof ( BITMAPV5HEADER );

    double _1px_p_m = 0.0002645833333333f;

    bitmap_info.bV5Size = sizeof ( BITMAPV5HEADER );
    bitmap_info.bV5Width = m_iPitch;
    bitmap_info.bV5Height = m_iRows;
    bitmap_info.bV5Planes = 1;
    bitmap_info.bV5BitCount = bytes_per_px * 8;
    bitmap_info.bV5Compression = BI_BITFIELDS;
    bitmap_info.bV5SizeImage = ( m_iPitch * m_iRows ) * 3;
    bitmap_info.bV5XPelsPerMeter = m_iPitch * _1px_p_m;
    bitmap_info.bV5YPelsPerMeter = m_iRows * _1px_p_m;
    bitmap_info.bV5ClrUsed = 0;
    bitmap_info.bV5ClrImportant = 0;
    bitmap_info.bV5RedMask = 0xFF000000;
    bitmap_info.bV5GreenMask = 0x00FF0000;
    bitmap_info.bV5BlueMask = 0x0000FF00;
    bitmap_info.bV5AlphaMask = 0x000000FF;
    bitmap_info.bV5CSType = LCS_WINDOWS_COLOR_SPACE;

    ...
     -> the other part does just write those structures & my px array to file

}

CBitmap "useful" 宏

i made macros for the pixel array because ive "changed" the pixel "format" many times -> to make it "easier" i have made those macros which make it easier todo that

#define bytes_per_px 4
#define px_red       0
#define px_green     1
#define px_blue      2
#define px_alpha     3

备注

这个计算是错误的:

&m_pBuffer [ ( m_iPitch * top ) + ( left * bytes_per_px ) ]

应该是:

&m_pBuffer [ ( ( m_iPitch * top ) + left ) * bytes_per_px ]

每行 m_iPitch * bytes_per_px 字节宽。如果你只是乘以 m_iPitch,那么你的 "rows" 就会相互重叠。