弄了一天了,还是不对!跪求帮助!关于对24位bmp位图像素数据数组的有关问题
弄了一天了,还是不对!跪求帮助!关于对24位bmp位图像素数据数组的问题!
本帖最后由 xyczy 于 2012-09-24 13:11:59 编辑 fread(&stBMPHeader, 1, sizeof(BITMAPFILEHEADER), hFile); //读取文件头
fread(&stBMPInfoHeader, 1, sizeof(BITMAPINFOHEADER), hFile); //读取位图信息头
if (stBMPHeader.bfType == 0x4D42) //这个是位图BMP的文件标识, 在这里判断是否为BMP文件
{
lpBitmapInfo = (BITMAPINFO*)new BYTE[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256];
if (stBMPInfoHeader.biBitCount == 8) //这里判断是否为8位位图, 如果是,则要把调色板读出来
{
fread(MainPalette, 1, sizeof(MainPalette), hFile);
}
//下面就是读取位图的像素数据了。
pByte = new BYTE[((((stBMPInfoHeader.biWidth * stBMPInfoHeader.biBitCount) + 31) / 32) * 4) * stBMPInfoHeader.biHeight];
fread(pByte, 1, ((((stBMPInfoHeader.biWidth * stBMPInfoHeader.biBitCount) + 31) / 32) * 4) * stBMPInfoHeader.biHeight, hFile);
BYTE *pByte2=pByte;
------------------------------------------------------
这是别人的一个代码,首先读取完成数据后通过 SetDIBitsToDevice(hDC, 0, 0, stBMPInfoHeader.biWidth, stBMPInfoHeader.biHeight, 0, 0,
0, stBMPInfoHeader.biHeight, pByte2, lpBitmapInfo, DIB_RGB_COLORS);
函数能正常显示图片
问题1:这个((((stBMPInfoHeader.biWidth * stBMPInfoHeader.biBitCount) + 31) / 32) * 4) * stBMPInfoHeader.biHeight每行的字节数算法能解释一下为什么要这样算吗,我的bmp是24位的,那每列字节数不是应该stBMPInfoHeader.biHeight*3吗为什么是stBMPInfoHeader.biHeight呢(这个算法能正确显示)
问题2:我想在显示前对图像数据进行处理
int width=(((stBMPInfoHeader.biWidth * stBMPInfoHeader.biBitCount) + 31) / 32) * 4;
int height=stBMPInfoHeader.biHeight*stBMPInfoHeader.biBitCount;
BYTE *pByte2=pByte;
for(int i=0;i<height;i++)
for(int j=0;j<width;j++)
{
if(i>=0&&i<=100&&j>=0&&j<=100)
{
pByte[width*i+j+2]-=20; //r
pByte[width*i+j+1]-=20; //g
pByte[width*i+j]-=20; //b
}
}
但是显示不正确如下图http://upload.gameres.com/20129/sf_24124956_9679.jpg,有人能告诉我i行j列的像素数据怎样表示吗
------最佳解决方案--------------------
biWidth当然是600,这个仅表示每行有多少个像素点,和你图像是否为彩色、还是灰度没关系。
我觉得你现在的问题是,没有弄清:每行的像素点数和每行像素所占字节数这两个概念;
//每行图像所占字节数,4字节对齐
int nLineBytes = (((stBMPInfoHeader.biWidth * stBMPInfoHeader.biBitCount) + 31) / 32) * 4;
//图像宽
int nWidth = stBMPInfoHeader.biWidth;
//图像高
int nHeight= stBMPInfoHeader.biHeight;
//
for(int i = 0; i < nHeight; i++)
{
for(int j = 0; j < nWidth; j++)
{
if(i>=0 && i<=100 && j>=0 && j<=100)
{
//这里注意是行下标乘每行数据所占字节数
pByte[nLineBytes*i + j*3+2] -= 20; //r
pByte[nLineBytes*i + j*3+1] -= 20; //g
本帖最后由 xyczy 于 2012-09-24 13:11:59 编辑 fread(&stBMPHeader, 1, sizeof(BITMAPFILEHEADER), hFile); //读取文件头
fread(&stBMPInfoHeader, 1, sizeof(BITMAPINFOHEADER), hFile); //读取位图信息头
if (stBMPHeader.bfType == 0x4D42) //这个是位图BMP的文件标识, 在这里判断是否为BMP文件
{
lpBitmapInfo = (BITMAPINFO*)new BYTE[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256];
if (stBMPInfoHeader.biBitCount == 8) //这里判断是否为8位位图, 如果是,则要把调色板读出来
{
fread(MainPalette, 1, sizeof(MainPalette), hFile);
}
//下面就是读取位图的像素数据了。
pByte = new BYTE[((((stBMPInfoHeader.biWidth * stBMPInfoHeader.biBitCount) + 31) / 32) * 4) * stBMPInfoHeader.biHeight];
fread(pByte, 1, ((((stBMPInfoHeader.biWidth * stBMPInfoHeader.biBitCount) + 31) / 32) * 4) * stBMPInfoHeader.biHeight, hFile);
BYTE *pByte2=pByte;
------------------------------------------------------
这是别人的一个代码,首先读取完成数据后通过 SetDIBitsToDevice(hDC, 0, 0, stBMPInfoHeader.biWidth, stBMPInfoHeader.biHeight, 0, 0,
0, stBMPInfoHeader.biHeight, pByte2, lpBitmapInfo, DIB_RGB_COLORS);
函数能正常显示图片
问题1:这个((((stBMPInfoHeader.biWidth * stBMPInfoHeader.biBitCount) + 31) / 32) * 4) * stBMPInfoHeader.biHeight每行的字节数算法能解释一下为什么要这样算吗,我的bmp是24位的,那每列字节数不是应该stBMPInfoHeader.biHeight*3吗为什么是stBMPInfoHeader.biHeight呢(这个算法能正确显示)
问题2:我想在显示前对图像数据进行处理
int width=(((stBMPInfoHeader.biWidth * stBMPInfoHeader.biBitCount) + 31) / 32) * 4;
int height=stBMPInfoHeader.biHeight*stBMPInfoHeader.biBitCount;
BYTE *pByte2=pByte;
for(int i=0;i<height;i++)
for(int j=0;j<width;j++)
{
if(i>=0&&i<=100&&j>=0&&j<=100)
{
pByte[width*i+j+2]-=20; //r
pByte[width*i+j+1]-=20; //g
pByte[width*i+j]-=20; //b
}
}
但是显示不正确如下图http://upload.gameres.com/20129/sf_24124956_9679.jpg,有人能告诉我i行j列的像素数据怎样表示吗
------最佳解决方案--------------------
biWidth当然是600,这个仅表示每行有多少个像素点,和你图像是否为彩色、还是灰度没关系。
我觉得你现在的问题是,没有弄清:每行的像素点数和每行像素所占字节数这两个概念;
//每行图像所占字节数,4字节对齐
int nLineBytes = (((stBMPInfoHeader.biWidth * stBMPInfoHeader.biBitCount) + 31) / 32) * 4;
//图像宽
int nWidth = stBMPInfoHeader.biWidth;
//图像高
int nHeight= stBMPInfoHeader.biHeight;
//
for(int i = 0; i < nHeight; i++)
{
for(int j = 0; j < nWidth; j++)
{
if(i>=0 && i<=100 && j>=0 && j<=100)
{
//这里注意是行下标乘每行数据所占字节数
pByte[nLineBytes*i + j*3+2] -= 20; //r
pByte[nLineBytes*i + j*3+1] -= 20; //g