请问:有个位图句柄hbitmap,怎么找到该位图句柄中的位图信息开始位置的指针?
有个位图句柄hbitmap,怎么找到该位图句柄中的位图信息开始位置的指针?
比如有个位图,位图分两部分。第一部分是头,第二部分是图素信息。怎么从hbitmap找到图素信息开始位子的指针。
本人初学,还请各位大哥们写详细点。谢谢。
问题点数:50、回复次数:8Top
1 楼laiyiling(陌生人[MVP])回复于 2004-09-01 19:25:04 得分 10
HANDLE hDIB;//位图句柄
BITMAPINFOHEADER *lpDIBInfoHeader;//指向位图的信息头的指针
BYTE *lpDIBBits;//指向位图数据的指针
lpDIBInfoHeader = (BITMAPINFOHEADER*)GlobalLock(hDIB);Top
2 楼wlzqi(wlzqi)回复于 2004-09-01 19:39:54 得分 10
使用CDib类
/*******************************************************************************
* 名 称:dib.h
* 模 块:
* 版 本:
* 版 权:
* 功 能:1.DIB文件的读、写操作
2.提供位图宽度、高度、颜色数目等位图相关信息
3.提供有关位图占据内存空间的信息,包括:图像数据区首地址、颜色表首
地址、位图信息结构首地址等信息
* 作 者:
* 建 立 时间:
* 建 立 者:
* 最后修改者:
*******************************************************************************/
//预编译头
#ifndef _DIB_H_
#define _DIB_H_
#pragma once
//
//******************************************************************************
//包含的头文件
#include "afx.h"
#include <windowsx.h>
//
//******************************************************************************
//
class CDib :
public CObject
{
public:
CDib(void);
~CDib(void);
protected:
/*******************************************************************************
* Windows位图结构数据域的含义 *
********************************************************************************
* 结构 数据域 含义 *
* RGBQUAD rgbBlue 蓝色的比例 *
* rgbGreen 绿的比例 *
* rgbRed 红色的比例 *
* rgbReserved 0 *
* BITMAPFILEHEADER bfType 字节“BM” *
* bfSize 文件总字节数 *
* BfReserved1 0 *
* bfOffBits 位图数据距文件头的偏移量 *
* BITMAPINFOHEADER biSize 本结构大小的字节数 *
* biWidth 位图的宽度,单位为像素点 *
* biHeight 位图的高度,单位为像素点 *
* biPlanes 1 *
* biBitCount 像素的位数(1,4,8,24) *
* biCompression 压缩方式(0表示不压缩) *
* biSizeImage 位图数据的字节数 *
* biXpelsPerMeter 水平分辨率(像素点/米) *
* biYpelsPerMeter 垂直分辨率(像素点/米) *
* biClrUsed 图像中使用的颜色数 *
* biCLrImportant 图像中重要的颜色数 *
*******************************************************************************/
// 保存颜色表首地址,被GetRGB()函数返回
RGBQUAD *m_pRGB;
// 保存图像数据首地址,被GetData()函数返回
BYTE *m_pData;
// 保存位图颜色数目,被GetNumberOfColors()函数返回
UINT m_numberOfColors;
// 判断加载位图是否有效。true---有效,false---无效即要打开的不是位图文件
bool m_valid;
BITMAPFILEHEADER bitmapFileHeader;
// BITMAPINFOHEADER * m_pBitmapInfoHeader;
//保存图像信息结构首地址,被GetInfo()函数返回
BITMAPINFO * m_pBitmapInfo;
BYTE * pDib;
DWORD size;
char m_fileName [256];
public:
//
// BITMAPFILEHEADER bitmapFileHeader;
//
BITMAPINFOHEADER * m_pBitmapInfoHeader;
// 装载bmp位图文件
bool LoadFile(const char * dibFileName);
// 存储bmp文件
bool SaveFile(const CString strfilename);
// 返回位图文件名
char * GetFileName(void);
// 判断加载位图后的状态。如果加载的是位图则true,否则false
bool IsValid(void);
// 返回位图文件的大小
DWORD GetSize(void);
// 返回位图的宽度
UINT GetWidth(void);
// 返回位图的高度
UINT GetHeight(void);
// 返回位图的颜色数目
UINT GetNumberOfColors(void);
// 返回颜色表的首地址
RGBQUAD * GetRGB(void);
// 返回图像数据首地址
BYTE * GetData(void);
// 返回图像信息结构首地址
BITMAPINFO * GetInfo(void);
// 返回调色盘大小
DWORD PaletteSize(LPBYTE lpDIB);
// 返回颜色位数
DWORD DIBNumColors(LPBYTE lpDIB);
};
#endif
Top
3 楼wlzqi(wlzqi)回复于 2004-09-01 19:40:24 得分 10
#include "StdAfx.h"
#include ".\dib.h"
CDib::CDib(void)
: m_pRGB(NULL)
, m_pData(NULL)
, m_numberOfColors(0)
, m_valid(FALSE)
, m_pBitmapInfoHeader(NULL)
, m_pBitmapInfo(NULL)
, pDib(NULL)
, size(0)
{
}
CDib::~CDib(void)
{
GlobalFreePtr ( m_pBitmapInfo );
}
/*******************************************************************************
* 函数名称:LoadFile(const char * dibFileName);
* 函数类型:bool
* 参数说明:dibFileName,将要装载的位图文件名。
* 功 能:装载bmp位图文件。
* 说 明:如果成功则返回true,否则返回false
*******************************************************************************/
bool CDib::LoadFile(const char * dibFileName)
{
strcpy ( m_fileName,dibFileName );
CFile dibFile ( m_fileName, CFile::modeRead );
dibFile.Read ( ( void * ) &bitmapFileHeader, sizeof ( BITMAPFILEHEADER ) );
// 文件时bmp格式吗?
// 如果成功
if ( bitmapFileHeader.bfType == 0x4d42 ) // bfType值是“BM”(0x4d42),标志该文件是位图文件
{
// 得到温度文件大小,并分配相应的内存空间
DWORD fileLength = dibFile.GetLength ();
size = fileLength - sizeof ( BITMAPFILEHEADER );
pDib = ( BYTE * )GlobalAllocPtr ( GMEM_MOVEABLE,size );
dibFile.Read ( ( void * ) pDib,size );
dibFile.Close ();
// 读取BITMAPINFOHEADER结构
m_pBitmapInfo = ( BITMAPINFO * )pDib;
m_pBitmapInfoHeader = ( BITMAPINFOHEADER * )pDib;
m_pRGB = ( RGBQUAD * )( pDib + m_pBitmapInfoHeader ->biSize );
int m_numberOfColors = GetNumberOfColors ();
if ( m_pBitmapInfoHeader->biClrUsed == 0 )
{
m_pBitmapInfoHeader->biClrUsed = m_numberOfColors;
}
// 计算像素数据的起始位置,保存像素数据起始位置指针
DWORD colorTableSize = m_numberOfColors * sizeof ( RGBQUAD );
m_pData = pDib + m_pBitmapInfoHeader->biSize + colorTableSize;
// 如果没有颜色索引
if ( m_pRGB == ( RGBQUAD * )m_pData )
{
m_pRGB = NULL;
}
m_pBitmapInfoHeader ->biSizeImage = GetSize ();
m_valid = true;
return m_valid;
}
//如果失败
else
{
m_valid = false;
return m_valid;
}
return false;
}
/*******************************************************************************
* 函数名称:SaveFile(const CString strfilename);
* 函数类型:bool
* 参数说明:filename,将要存储的位图文件名。
* 功 能:存储bmp文件
* 说 明:如果成功则返回true,否则返回false
* 此函数只能保存经过处理后宽度、高度均没有改变的图像
*******************************************************************************/
bool CDib::SaveFile(const CString strfilename)
{
if ( strfilename.GetLength () == 0 )
{
return false;
}
else
{
strcpy ( m_fileName,strfilename );
CFile dibFile ( m_fileName,CFile::modeCreate | CFile::modeWrite );
dibFile.Write ( ( void * )&bitmapFileHeader,sizeof ( BITMAPFILEHEADER ) );
dibFile.Write ( ( void * )pDib,size );
dibFile.Close ();
return true;
}
return false;
}
// 返回位图文件名
char * CDib::GetFileName(void)
{
return m_fileName;
}
// 判断加载位图后的状态。如果加载的是位图则true,否则false
bool CDib::IsValid(void)
{
return m_valid;
}
// 返回位图文件的大小
DWORD CDib::GetSize(void)
{
// 如果文图数据字节数不为零
if ( m_pBitmapInfoHeader->biSizeImage != 0 )
{
// 返回字节数
return m_pBitmapInfoHeader->biSizeImage ;
}
else
{
DWORD height = ( DWORD )GetHeight ();
DWORD width = ( DWORD )GetWidth ();
// 返回位图高、宽之乘积
return height * width ;
}
}
// 返回位图的宽度
UINT CDib::GetWidth(void)
{
return ( UINT )m_pBitmapInfoHeader->biWidth ;
}
// 返回位图的高度
UINT CDib::GetHeight(void)
{
return ( UINT )m_pBitmapInfoHeader->biHeight ;
}
// 返回位图的颜色数目
UINT CDib::GetNumberOfColors(void)
{
// 颜色数目
long numberOfColors;
// 如果图像中使用的颜色数目为零,并且像素位数小于9
if ( ( m_pBitmapInfoHeader->biClrUsed == 0 ) && ( m_pBitmapInfoHeader->biBitCount < 9 ) )
{
// 如果像数位数小于9,则当像素位数分别为 1,4,8 时,位图的颜色数依次为 2,16,256
switch ( m_pBitmapInfoHeader->biBitCount )
{
case 1:numberOfColors = 2;break;
case 4:numberOfColors = 16;break;
case 8:numberOfColors = 256;break;
}
}
// 如果图像中使用的颜色数目不为零,得到颜色数
else
{
numberOfColors = ( int )m_pBitmapInfoHeader->biClrUsed ;
}
// 最后返回得到的颜色数
return numberOfColors;
}
// 返回颜色表的首地址
RGBQUAD * CDib::GetRGB(void)
{
return m_pRGB;
}
// 返回图像数据首地址
BYTE * CDib::GetData(void)
{
return m_pData;
}
// 返回图像信息结构首地址
BITMAPINFO * CDib::GetInfo(void)
{
return m_pBitmapInfo;
}
/*******************************************************************************
* 函数名称:PaletteSize(LPBYTE lpDIB);
* 函数类型:WORD
* 参数说明:lpDIB
* 功 能:返回调色盘大小
* 说 明:
*******************************************************************************/
DWORD CDib::PaletteSize(LPBYTE lpDIB)
{
return ( DIBNumColors ( lpDIB ) * sizeof ( RGBTRIPLE ) );
}
/*******************************************************************************
* 函数名称:DIBNumColors(LPBYTE lpDIB);
* 函数类型:WORD
* 参数说明:lpDIB
* 功 能:返回颜色位数
* 说 明:
*******************************************************************************/
DWORD CDib::DIBNumColors(LPBYTE lpDIB)
{
// DIB位数
WORD wBitCount;
wBitCount = ( ( LPBITMAPCOREHEADER )lpDIB )->bcBitCount ;
switch ( wBitCount )
{
case 1:return 2;break;
case 4:return 16;break;
case 8:return 256;break;
default:return 0;break;
}
}
Top
4 楼huwei001982(凶猛的小狗)回复于 2004-09-01 21:09:53 得分 10
楼上的贴得真详细!
只需用这个函数即可:
::GetDIBits(HDC, HBITMAP, UINT, UINT, LPVOID, LPBITMAPINFO, UINT);
HDC: 设备场景
HBITMAP:位图句柄
UINT:起始扫描线, 设为 0
UINT:图片的高度
LPVOID:分配一个缓冲区来接收图片的数据, 例如 BYTE *pBuf = new BYTE[3541021];
LPBITMAPINFO:图片信息
UINT: 设为: DIB_RGB_COLORS
仅知道 HBITMAP是不够的, 还要知道 HDC, BITMAPINFO
Top
5 楼lanstar200(待我景天大侠斩妖除魔)回复于 2004-09-02 08:54:25 得分 10
BOOL CTestDlg::SaveBmp(HBITMAP hBitmap, LPSTR FileName)
{
HDC hDC;
int iBits;
WORD wBitCount;
DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0;
BITMAP Bitmap;
BITMAPFILEHEADER bmfHdr;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
HANDLE fh, hDib, hPal,hOldPal=NULL;
hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits <= 1) wBitCount = 1;
else if (iBits <= 4) wBitCount = 4;
else if (iBits <= 8) wBitCount = 8;
else wBitCount = 24;
GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrImportant = 0;
bi.biClrUsed = 0;
dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;
hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;
hPal = GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
hDC = ::GetDC(NULL);
hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);
RealizePalette(hDC);
}
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
+dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS);
if (hOldPal)
{
::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
::ReleaseDC(NULL, hDC);
}
fh = CreateFile(FileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE) return FALSE;
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(fh);
return TRUE;
}Top
6 楼333sunshine(风)回复于 2004-09-02 09:58:10 得分 0
GetDIBits()是相当于把hBitmap里面的图素信息复制到了一个缓冲里面。再来对缓冲里面的数据进行操作。
能不能直接找到hBitmap里面的图素信息的地址?Top
7 楼333sunshine(风)回复于 2004-09-02 13:26:40 得分 0
是不是这个没法做到?Top
8 楼333sunshine(风)回复于 2004-09-04 20:54:39 得分 0
再顶一下!!Top




