游戏开发论坛

 找回密码
 立即注册
搜索
查看: 1771|回复: 2

关于生成BMP文件的一个问题

[复制链接]

5

主题

21

帖子

27

积分

注册会员

Rank: 2

积分
27
发表于 2007-6-9 22:42:00 | 显示全部楼层 |阅读模式
这是我在圣剑源码里看到的一段生成BMP文件的函数
bool SaveToBitmapFile(LPDIRECTDRAWSURFACE7 lpSurface, char* filename)
{
        WORD* lpBuffer;                        // 表面指针
        int nPitch;                         // 表面跨距
        int nWidth=0, nHeight=0;        // 表面宽高
       
        // 打开文件
        FILE* fp;
        if( (fp=fopen(filename, "wb")) != NULL )
        {
                // 锁定表面
                DDSURFACEDESC2 ddsd;
                ddsd.dwSize = sizeof(ddsd);
                //ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;

                HRESULT ddrval = lpSurface->Lock( NULL, &ddsd, DDLOCK_WAIT, NULL );
                if( ddrval == DD_OK )
                {

                          lpBuffer = (WORD *)ddsd.lpSurface;
                        nWidth = ddsd.dwWidth;
                        nHeight = ddsd.dwHeight;
                        //lPitch以Byte为单位计数的,GraphPitch以WORD为单位。所以GraphPitch = lPitch / 2;
                        nPitch  = ddsd.lPitch >> 1;       

                }
       
                // 保存文件头
                BITMAPFILEHEADER FileHeader;
                FileHeader.bfType = 'BM';        //把这里得BM改成MB便可以了,这是为什么呢
                FileHeader.bfSize = nWidth * nHeight * 3 + 0x36;
                FileHeader.bfReserved1 = 0;
                FileHeader.bfReserved2 = 0;
                FileHeader.bfOffBits = 0x36;
                fwrite(&FileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
               
                // 保存文件信息
                BITMAPINFOHEADER Header;
                Header.biSize = sizeof(BITMAPINFOHEADER);        // 结构的大小
                Header.biWidth = nWidth;                                        // 宽
                Header.biHeight = nHeight;                                        // 高
                Header.biPlanes = 1;                                                // 固定
                Header.biBitCount = 24;                                                // 颜色数
                Header.biCompression = BI_RGB;                                // 是否压缩
                Header.biSizeImage = nWidth * nHeight * 3;        // 图片的大小
                Header.biXPelsPerMeter = 0;
                Header.biYPelsPerMeter = 0;
                Header.biClrUsed = 0;
                Header.biClrImportant = 0;
                fwrite(&Header, Header.biSize, 1, fp);
               
                fseek(fp,-(int)(nWidth*nHeight*3),SEEK_END);
                PutDebugNumber((int)(nWidth*nHeight*3));

                WORD word;
                lpBuffer += nWidth * (nHeight - 1);
               
                char c='a';

                for(int i=0; i<nHeight; i++)
                {
                        for(int j=0; j<nWidth; j++)
                        {
                                word = *lpBuffer;
                                fputc( GetBlue( word ), fp);        // 蓝
                                fputc( GetGreen( word ), fp);        // 绿
                                fputc( GetRed( word ), fp);                // 红
                                lpBuffer++;
                        }

                        lpBuffer -= nPitch*2;        // 指针转到上一行的开始
                }
                fclose(fp);
       
                // 解锁表面
                ddrval = lpSurface->Unlock( NULL );
                return true;
        }

        return false;
}


原函数的的FileHeader.bfType 值为 'BM'
但我使用这个函数生成的图片无法浏览,我用记事本打开生成的文件发现,左上角的值是"MB",可我明明附得是BM啊!无奈之下,我把FileHeader.bfType的值改成MB,再使用该函数,这次生成的图片是可以浏览的。打开生成的图片,左上角的值是BM。为什么会保存成相反的值呢?FileHeader.bfType的值应该设成多少呢?

32

主题

1583

帖子

1589

积分

金牌会员

Rank: 6Rank: 6

积分
1589
发表于 2007-6-10 11:04:00 | 显示全部楼层

Re:关于生成BMP文件的一个问题

80x86 的 CPU 都是little Endian 的,一个WORD型的变量,在内存中的存储顺序是先低位后高位,当然就反过来啦。

5

主题

21

帖子

27

积分

注册会员

Rank: 2

积分
27
 楼主| 发表于 2007-6-10 17:41:00 | 显示全部楼层

Re:关于生成BMP文件的一个问题

谢谢sandy_zc_1的解答,我基本明白了
如果把FileHeader.bfType = 'BM' 改成 FileHeader.bfType = *(WORD*)"BM" 也能成功保存图片
我的理解是WORD*把"BM"字符串的地址转化为WORD*格式的,然后取该地址上的WORD类型数值。

FileHeader.bfType='BM'  字符'B'和'M'应该是按顺序存放到地址上的,假设先把字符B放到地址0001上,再把字符M放到地址0002上。所以当我们读取FileHeader.bfType的值时发现其值是MB,而不是BM
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-26 04:33

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表