100分求助:一个24位彩色bmp变8位灰度图像的程序,运行结果产生左右颠倒的问题。 一个24位彩色bmp变8位灰度图像的程序,运行结果产生左右颠倒的问题。大家给点意见,问题解决后,马上给分。QQ:270946410 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 这是我的变换程序HDIB hGreyDIB=NULL; DWORD nWide,nHeight,i,j; //预定义 LPBYTE lpBit=(LPBYTE)GlobalLock( (HGLOBAL)hDib); nWide = DIBWidth(lpBit); nHeight = DIBHeight(lpBit); LPBITMAPINFOHEADER pHeader=(LPBITMAPINFOHEADER)lpBit; DWORD dGrayDIBSize; if(IS_WIN30_DIB(lpBit)) dGrayDIBSize=pHeader->biSize+256*sizeof(RGBQUAD)+(nWide*8+31)/32*4*nHeight; else dGrayDIBSize=pHeader->biSize+256*sizeof(RGBTRIPLE)+(nWide*8+31)/32*4*nHeight; hGreyDIB=(HDIB)GlobalAlloc(GHND,dGrayDIBSize); LPBITMAPINFO lpGray=(LPBITMAPINFO)GlobalLock((HGLOBAL)hGreyDIB); lpGray->bmiHeader=*pHeader; lpGray->bmiHeader.biBitCount=8; lpGray->bmiHeader.biHeight=nHeight; lpGray->bmiHeader.biWidth=(WORD)( (nWide + 3) /4 ) * 4; lpGray->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); if(IS_WIN30_DIB(lpBit)) for(i=0;i<256;i++) { lpGray->bmiColors[i].rgbBlue=(BYTE)i; lpGray->bmiColors[i].rgbGreen=(BYTE)i; lpGray->bmiColors[i].rgbRed=(BYTE)i; lpGray->bmiColors[i].rgbReserved=(BYTE)0; } else for(i=0;i<256;i++) { lpGray->bmiColors[i].rgbBlue=(BYTE)i; lpGray->bmiColors[i].rgbGreen=(BYTE)i; lpGray->bmiColors[i].rgbRed=(BYTE)i; } LPBYTE lpGrayBit=(LPBYTE)lpGray; if(IS_WIN30_DIB(lpBit)) lpGrayBit+=pHeader->biSize+256*sizeof(RGBQUAD); else lpGrayBit+=pHeader->biSize+256*sizeof(RGBTRIPLE); int nCountBit=pHeader->biBitCount; // lpGrayBit=FindDIBBits(lpBit); if(nCountBit>8) { lpBit+=sizeof(BITMAPINFOHEADER); int nRGB=(nWide*nCountBit+31)/32*4-nWide*nCountBit/8; int nGrey=(nWide*8+31)/32*4-nWide; for(i=0;i<nHeight;i++) { for(j=0;j<nWide;j++) { *lpGrayBit++=(unsigned char)((*lpBit++)*0.299+(*lpBit++)*0.587+(*lpBit++)*0.114); // *lpGrayBit++=0; } lpGrayBit+=nGrey; lpBit+=nRGB; } ::GlobalUnlock((HGLOBAL) hDib); ::GlobalFree((HGLOBAL) hDib); ::GlobalUnlock((HGLOBAL)hGreyDIB); hDib = hGreyDIB; // WaitCursorEnd(); return hDib; bmp文件存放数据格式是从下到上,从左往右 你的代码应该是上下颠倒for(i=0;i<nHeight;i++) 改成 for(i=nHeight-1;i>=0;i--) for(i=0;i<nHeight;i++) { for(j=0;j<nWide;j++) {两个循环换个位置 效果没有什么变化。to pomelowu(羽战士) :能不能具体指教一下呢? bmp文件存放数据格式行行之间是从下到上,每一行内是从左往右 。而且BMP文件存储是低位在前,高位在后。 跟位图结构应该关系不大。因为原图和目标两个都反就不存在这个问题了。要不lz试试把biWidth改成负的吧,看能不能暂时解决这个问题。 位图数据,无论是top-down还是bottom-up,左右都是固定的。呃就是说,像素间肯定是从左到右这样的排列顺序:(0,0)(1,0)(2,0)... 只是第0行在顶上或者在下面的问题。而如果是左右颠倒,那么只是循环出了问题。而楼主的循环是先行后列,也就是先取(0,0)像素的第一个分量处理,紧接着取(0,1)像素的第一个分量处理... 自然就会出现偏差可能读代码不精,误导楼主。不过思路是这样,自己检查下代码吧。 RunUi界面开发包邀请测试! ATL复合控件不响应键盘消息? flexgrid 换行 , 设置行宽 读文件的错误? ★☆★到老家来求点东西,有兴趣的朋友进★☆★ 一个简单的问题 急 求救,我需要在CHelloDialog中调用CHelloCtrl的Funct(); MSDN.Library.January.2004 编程用的,好东西。地球人都知道!^-^ ATL 中的消息响应函数 请问在mfc的框架里,如何屏蔽快捷键CTRL+N MFC 如何写退出程序的BUTTON HID复合设备在HID类的枚举过程中出现的疑问?
HDIB hGreyDIB=NULL;
DWORD nWide,nHeight,i,j; //预定义
LPBYTE lpBit=(LPBYTE)GlobalLock( (HGLOBAL)hDib);
nWide = DIBWidth(lpBit);
nHeight = DIBHeight(lpBit);
LPBITMAPINFOHEADER pHeader=(LPBITMAPINFOHEADER)lpBit;
DWORD dGrayDIBSize;
if(IS_WIN30_DIB(lpBit))
dGrayDIBSize=pHeader->biSize+256*sizeof(RGBQUAD)+(nWide*8+31)/32*4*nHeight;
else
dGrayDIBSize=pHeader->biSize+256*sizeof(RGBTRIPLE)+(nWide*8+31)/32*4*nHeight;
hGreyDIB=(HDIB)GlobalAlloc(GHND,dGrayDIBSize);
LPBITMAPINFO lpGray=(LPBITMAPINFO)GlobalLock((HGLOBAL)hGreyDIB);
lpGray->bmiHeader=*pHeader;
lpGray->bmiHeader.biBitCount=8;
lpGray->bmiHeader.biHeight=nHeight; lpGray->bmiHeader.biWidth=(WORD)( (nWide + 3) /4 ) * 4;
lpGray->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
if(IS_WIN30_DIB(lpBit))
for(i=0;i<256;i++)
{
lpGray->bmiColors[i].rgbBlue=(BYTE)i;
lpGray->bmiColors[i].rgbGreen=(BYTE)i;
lpGray->bmiColors[i].rgbRed=(BYTE)i;
lpGray->bmiColors[i].rgbReserved=(BYTE)0;
}
else
for(i=0;i<256;i++)
{
lpGray->bmiColors[i].rgbBlue=(BYTE)i;
lpGray->bmiColors[i].rgbGreen=(BYTE)i;
lpGray->bmiColors[i].rgbRed=(BYTE)i;
}
LPBYTE lpGrayBit=(LPBYTE)lpGray;
if(IS_WIN30_DIB(lpBit))
lpGrayBit+=pHeader->biSize+256*sizeof(RGBQUAD);
else
lpGrayBit+=pHeader->biSize+256*sizeof(RGBTRIPLE);
int nCountBit=pHeader->biBitCount;
// lpGrayBit=FindDIBBits(lpBit);
if(nCountBit>8)
{
lpBit+=sizeof(BITMAPINFOHEADER); int nRGB=(nWide*nCountBit+31)/32*4-nWide*nCountBit/8;
int nGrey=(nWide*8+31)/32*4-nWide;
for(i=0;i<nHeight;i++)
{
for(j=0;j<nWide;j++)
{
*lpGrayBit++=(unsigned char)((*lpBit++)*0.299+(*lpBit++)*0.587+(*lpBit++)*0.114);
// *lpGrayBit++=0;
}
lpGrayBit+=nGrey;
lpBit+=nRGB;
}
::GlobalUnlock((HGLOBAL) hDib);
::GlobalFree((HGLOBAL) hDib);
::GlobalUnlock((HGLOBAL)hGreyDIB);
hDib = hGreyDIB;
// WaitCursorEnd();
return hDib;
你的代码应该是上下颠倒
for(i=0;i<nHeight;i++) 改成 for(i=nHeight-1;i>=0;i--)
{
for(j=0;j<nWide;j++)
{两个循环换个位置