绘制BMP位图文件

原创 2004年08月30日 01:15:00
绘制BMP位图文件
 
    BMP文件由三部分组成:有关文件信息的BITMAPFILEHEADER,有关位图
信息的BITMAPINFO以及位图的图象数据。其中BITMAPINFO又由位图信息头
BITMAPINFOHEADER和颜色表组成,颜色表不是
必须的。
几个结构的定义可查看联机帮助。一旦把BMP位图读入内存后,只要用上一
篇介绍的显示位图的
方法就可以显示了。
函数1:装载位图文件,生成位图GDI对象,用DDB方法显示。
// LoadBMPImage - 装载BMP位图,创建位图GDI对象同时创建位图调色板
// Returns - 返回TRUE成功
// sBMPFile - 全路经BMP文件
// bitmap - 将被初始化的位图对象
// pPal         - 将被初始化的位图调色板,可为NULL
BOOL LoadBMPImage( LPCTSTR sBMPFile, CBitmap& bitmap, CPalette *pPal )
{
CFile file;
if( !file.Open( sBMPFile, CFile::modeRead) )
return FALSE;

BITMAPFILEHEADER bmfHeader;

//读文件头
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
return FALSE;

// 文件类型标志是否为‘BM’
if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
return FALSE;

//获得文件将需的内存数
DWORD nPackedDIBLen = file.GetLength() - sizeof(BITMAPFILEHEADER);
HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nPackedDIBLen);
if (hDIB == 0)
return FALSE;

// 读余下的位图文件
if (file.ReadHuge((LPSTR)hDIB, nPackedDIBLen) != nPackedDIBLen )
{
::GlobalFree(hDIB);
return FALSE;
}


BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB ;
BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;

// 位图颜色数
int nColors = bmiHeader.biClrUsed ? bmiHeader.biClrUsed :
1 << bmiHeader.biBitCount;

LPVOID lpDIBBits;
if( bmInfo.bmiHeader.biBitCount > 8 )
lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
else
lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);

// 创建逻辑调色板
if( pPal != NULL )
{
if( nColors <= 256 )
{
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];

pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;

for( int i=0; i < nColors; i++)
{
pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
}

pPal->CreatePalette( pLP );

delete[] pLP;
}
}

CClientDC dc(NULL);
CPalette* pOldPalette = NULL;
if( pPal )
{
pOldPalette = dc.SelectPalette( pPal, FALSE );
dc.RealizePalette();
}

HBITMAP hBmp = CreateDIBitmap( dc.m_hDC, // 设备句柄
&bmiHeader, // pointer to bitmap size and format data
CBM_INIT, // initialization flag
lpDIBBits, // pointer to initialization data
&bmInfo, // pointer to bitmap color-format data
DIB_RGB_COLORS); // color-data usage
bitmap.Attach( hBmp );

if( pOldPalette )
dc.SelectPalette( pOldPalette, FALSE );

::GlobalFree(hDIB);
return TRUE;
}

函数2:装载位图文件,生成位图设备句柄,用DIB方法显示。
// LoadBMP - 装载位图文件,获得位图句柄与位图调色板
// Returns - 返回TRUE成功
// sBMPFile - 全路径BMP文件
// phDIB - 指向一个巳分配的HGLOBAL句柄
// pPal - 指向位图调色板
BOOL LoadBMP( LPCTSTR sBMPFile, HGLOBAL *phDIB, CPalette *pPal )
{
CFile file;
if( !file.Open( sBMPFile, CFile::modeRead) )
return FALSE;

BITMAPFILEHEADER bmfHeader;
long nFileLen;

nFileLen = file.GetLength();


// Read file header
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
return FALSE;

// File type should be 'BM'
if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
return FALSE;

HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nFileLen);
if (hDIB == 0)
return FALSE;

// Read the remainder of the bitmap file.
if (file.ReadHuge((LPSTR)hDIB, nFileLen - sizeof(BITMAPFILEHEADER)) !=
nFileLen - sizeof(BITMAPFILEHEADER) )
{
::GlobalFree(hDIB);
return FALSE;
}



BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;

int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :
1 << bmInfo.bmiHeader.biBitCount;

// Create the palette
if( nColors <= 256 )
{
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];

pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;

for( int i=0; i < nColors; i++)
{
pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
}

pPal->CreatePalette( pLP );

delete[] pLP;
}

*phDIB = hDIB;
return TRUE;
}

C/C++ BMP(24位真彩色)图像处理(1)------图像の打开与数据区处理

在图像处理过程中,通常以MATLAB代码进行模拟,
  • oHanTanYanYing
  • oHanTanYanYing
  • 2014年04月20日 17:44
  • 3736

使用freetype库将文字嵌入到bmp图片中 学习笔记

首先需要打开一张bmp图片,将图片读入内存中。然后连接freetype类库,使用的是freetype2.4.9版本,VS2010。 为了简单处理,使用的bmp图片为24位位图,960*540大小的一张...
  • u010385177
  • u010385177
  • 2015年07月17日 16:42
  • 1535

24/16/8位bmp图片文件头、信息头的二进制数据

24/16/8位bmp图片文件头、信息头的二进制数据 不知道第几次看这个了,今天再次看的时候 发现又回到了晕晕乎乎的感觉 用PS新建了10*10像素的24位bmp图片,用UE打开仔细瞧瞧 ...
  • flyfight88
  • flyfight88
  • 2013年01月15日 09:59
  • 2069

将RGB数据写入BMP位图文件

CFile file; //定义一个文件对象 _ASSERTE(file.Open(CString("E:\\94.bmp"), CFil...
  • u014568921
  • u014568921
  • 2015年09月11日 11:41
  • 1671

BMP位图文件的存储格式

位图是最常用的windows图形格式,通过windows API函数可以直接读取并绘制,不过,有时我们还是需要自己控制,那么,就让我们看看他的格式吧! 位图文件结构表 位图文件 位图文件头 1...
  • u012836490
  • u012836490
  • 2015年05月18日 11:35
  • 307

将HBITMAP转换成BMP位图文件的各个部分,可以在1BIT,4BIT,8BIT,16BIT,24BIT,32BIT之间转换

  VC将HBITMAP转换成BMP位图文件的各个部分,可以在1BIT,4BIT,8BIT,16BIT,24BIT,32BIT之间转换http://blog.ednchina.com/wxleasyl...
  • ding_net
  • ding_net
  • 2011年06月21日 13:07
  • 1789

VC用ADO存取显示jpg/bmp位图文件

周六和今天两天的时间,把数据库关于图片的存储和显示 实现了,虽然时间有点长,但是还是实现了。以下是网上找到的资料,很有用。 http://hi.baidu.com/%B0%A2%B3%ACyuch/...
  • eryadabendan
  • eryadabendan
  • 2011年09月05日 15:35
  • 1044

BMP 位图文件解析 解码 C++

  • 2011年05月05日 16:52
  • 411KB
  • 下载

Creating a bitmap object from a BMP file从位图文件中创建位图

  • 2006年02月23日 09:05
  • 5KB
  • 下载

BMP位图文件结构及平滑缩放

-- 用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重,在低颜色位数的设备上显示高颜色位数的图形图形时失真大。本文采用视频函数显示BMP位图,可以消除以上的缺点。 ----...
  • rushkid02
  • rushkid02
  • 2013年07月17日 11:23
  • 1029
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:绘制BMP位图文件
举报原因:
原因补充:

(最多只允许输入30个字)