请教如何在VC下读取bmp文件的rgb像素值?

cobefan 2006-04-15 10:20:29
看似简单,一直没调出来
有没有大虾知道,谢了
...全文
1059 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
cobefan 2006-04-16
  • 打赏
  • 举报
回复
谢谢楼上指教!
这个问题已经得到解决了:)
sboom 2006-04-16
  • 打赏
  • 举报
回复
http://blog.csdn.net/sboom/archive/2004/12/25/229044.aspx
soaroc 2006-04-16
  • 打赏
  • 举报
回复
《精通VisualC++ 图像处理源程序》

自定义的一个函数,不过先得用CreateFile获取hFile句柄。
HANDLE LoadDIB(LPCTSTR lpFileName)
{
HANDLE hDIB;
HANDLE hFile;

// Set the cursor to a hourglass, in case the loading operation
// takes more than a sec, the user will know what's going on.

SetCursor(LoadCursor(NULL, IDC_WAIT));

if ((hFile = CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
NULL)) != INVALID_HANDLE_VALUE)
{
hDIB = ReadDIBFile(hFile);
CloseHandle(hFile);
SetCursor(LoadCursor(NULL, IDC_ARROW));
return hDIB;
}
else
{
SetCursor(LoadCursor(NULL, IDC_ARROW));
return NULL;
}
}
然后:
HANDLE ReadDIBFile(HANDLE hFile)
{
BITMAPFILEHEADER bmfHeader;
DWORD dwBitsSize;
UINT nNumColors; // Number of colors in table
HANDLE hDIB;
HANDLE hDIBtmp; // Used for GlobalRealloc() //MPB
LPBITMAPINFOHEADER lpbi;
DWORD offBits;
DWORD dwRead;

// get length of DIB in bytes for use when reading

dwBitsSize = GetFileSize(hFile, NULL);

// Allocate memory for header & color table. We'll enlarge this
// memory as needed.

hDIB = GlobalAlloc(GMEM_MOVEABLE, (DWORD)(sizeof(BITMAPINFOHEADER) +
256 * sizeof(RGBQUAD)));

if (!hDIB)
return NULL;

lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);

if (!lpbi)
{
GlobalFree(hDIB);
return NULL;
}

// read the BITMAPFILEHEADER from our file

if (!ReadFile(hFile, (LPBYTE)&bmfHeader, sizeof (BITMAPFILEHEADER),
&dwRead, NULL))
goto ErrExit;

if (sizeof (BITMAPFILEHEADER) != dwRead)
goto ErrExit;

if (bmfHeader.bfType != 0x4d42) // 'BM'
goto ErrExit;

// read the BITMAPINFOHEADER

if (!ReadFile(hFile, (LPBYTE)lpbi, sizeof(BITMAPINFOHEADER), &dwRead,
NULL))
goto ErrExit;

if (sizeof(BITMAPINFOHEADER) != dwRead)
goto ErrExit;

// Check to see that it's a Windows DIB -- an OS/2 DIB would cause
// strange problems with the rest of the DIB API since the fields
// in the header are different and the color table entries are
// smaller.
//
// If it's not a Windows DIB (e.g. if biSize is wrong), return NULL.

if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
goto ErrExit;

// Now determine the size of the color table and read it. Since the
// bitmap bits are offset in the file by bfOffBits, we need to do some
// special processing here to make sure the bits directly follow
// the color table (because that's the format we are susposed to pass
// back)

if (!(nNumColors = (UINT)lpbi->biClrUsed))
{
// no color table for 24-bit, default size otherwise

if (lpbi->biBitCount != 24)
nNumColors = 1 << lpbi->biBitCount; // standard size table
}

// fill in some default values if they are zero

if (lpbi->biClrUsed == 0)
lpbi->biClrUsed = nNumColors;

if (lpbi->biSizeImage == 0)
{
lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) +
31) & ~31) >> 3) * lpbi->biHeight;
}

// get a proper-sized buffer for header, color table and bits

GlobalUnlock(hDIB);
hDIBtmp = GlobalReAlloc(hDIB, lpbi->biSize + nNumColors *
sizeof(RGBQUAD) + lpbi->biSizeImage, 0);

if (!hDIBtmp) // can't resize buffer for loading
goto ErrExitNoUnlock; //MPB
else
hDIB = hDIBtmp;

lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);

// read the color table

ReadFile (hFile, (LPBYTE)(lpbi) + lpbi->biSize,
nNumColors * sizeof(RGBQUAD), &dwRead, NULL);

// offset to the bits from start of DIB header

offBits = lpbi->biSize + nNumColors * sizeof(RGBQUAD);

// If the bfOffBits field is non-zero, then the bits might *not* be
// directly following the color table in the file. Use the value in
// bfOffBits to seek the bits.

if (bmfHeader.bfOffBits != 0L)
SetFilePointer(hFile, bmfHeader.bfOffBits, NULL, FILE_BEGIN);

if (ReadFile(hFile, (LPBYTE)lpbi + offBits, lpbi->biSizeImage, &dwRead,
NULL))
goto OKExit;

ErrExit:
GlobalUnlock(hDIB);

ErrExitNoUnlock:
GlobalFree(hDIB);
return NULL;

OKExit:
GlobalUnlock(hDIB);
return hDIB;
}
再读取像素数据
COLORREF CDib::GetPixel(LONG x, LONG y)
{
COLORREF cColor;
switch (GetBitCount())
{
case 1 : if (1<<(7-x%8) &
*(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y)))
cColor = RGB(255,255,255);
else
cColor = RGB(0,0,0);
break;
case 4 :
{
PALETTEENTRY PaletteColors[16];
m_pPalette->GetPaletteEntries(0, 16, PaletteColors);
int nIndex = (*(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y)) &
(x%2 ? 0x0f : 0xf0)) >> (x%2 ? 0 : 4);
cColor = RGB(PaletteColors[nIndex].peRed,
PaletteColors[nIndex].peGreen,
PaletteColors[nIndex].peBlue);
}
break;
case 8 :
{
PALETTEENTRY PaletteColors[256];
m_pPalette->GetPaletteEntries(0, 256, PaletteColors);
int nIndex = *(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y));
cColor = RGB(PaletteColors[nIndex].peRed,
PaletteColors[nIndex].peGreen,
PaletteColors[nIndex].peBlue);
}
break;
default: cColor = RGB(*(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y)),
*(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y)+1),
*(BYTE*)(GetBitsPtr()+GetPixelOffset(x, y)+2));
break;
}
return cColor;
}

LONG CDib::GetPixelOffset(LONG x, LONG y)
{
return (GetHeight()-y-1)*GetWidthBytes()+x/(8/GetBitCount());
}

LPBYTE CDib::GetBitsPtr()
{
LPBYTE lpDIB = (LPBYTE)GlobalLock(m_hDib);
if (! lpDIB)
{
GlobalUnlock(m_hDib);
return NULL;
}

LPBYTE lpData = FindDIBBits(lpDIB);
GlobalUnlock(m_hDib);

return lpData;
}
以上的知识要用到位图的相应的结构知识
菜牛 2006-04-15
  • 打赏
  • 举报
回复
你可以直接用CFile读取,根据位图格式定位到数据;或者用LoadImage转载位图到内存,然后用GetDIBits得到数据指针。

19,464

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧