100求教~~如何将指定位置的bmp图片像素值保存到一个数组中?
如题,想要设计一个按钮,按下以后,就可以读取硬盘上指定位置的bmp图片像素值保存到一个二维数组(图宽*图高)中,要怎样实现呢?
我根据网上的资料,写了一段= =查了下论坛,问这个问题的人很多,不过他们的答案我都不太明白,而且不能实现。附上我写的,请各位高手帮我修改下,或者给出有用的。
最理想的目标是获取图片每个点的rgb值,并保存在二维数组中
- C/C++ code
void CImageBoardView::OnTest() { //load bmp file:"d:\\lego1.bmp" CDC* pDC; pDC=GetDC( ); CImageBoardDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here HBITMAP hbmp=(HBITMAP)LoadImage(NULL,"d:\\lego1.bmp",IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE); CBitmap cbmp; cbmp.Attach(hbmp); BITMAP bmp; cbmp.GetBitmap(&bmp); cbmp.Detach(); UINT * pData = new UINT[bmp.bmWidth * bmp.bmHeight]; BITMAPINFO bmpInfo; bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth = bmp.bmWidth; bmpInfo.bmiHeader.biHeight = -bmp.bmHeight; bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biBitCount = 32; GetDIBits(pDC->m_hDC,hbmp,0,bmp.bmHeight,pData,&bmpInfo,DIB_RGB_COLORS); UINT color, r, g, b; for(int i = 0; i < bmp.bmWidth * bmp.bmHeight; i ++) { color = pData[i]; b = color << 8 >> 24; g = color << 16 >> 24; r = color << 24 >> 24; //note that infact, the r is Blue, b = Red, r = 0;//mask the blue bits pData[i] = RGB(r, g, b); } SetDIBits(pDC->m_hDC, hbmp,0, bmp.bmHeight, pData,&bmpInfo, DIB_RGB_COLORS); CDC dcmem; dcmem.CreateCompatibleDC(pDC); HGDIOBJ hold=::SelectObject(dcmem.m_hDC,hbmp); pDC->BitBlt(0,0,bmp.bmWidth,bmp.bmHeight,&dcmem,0,0,SRCCOPY); ::SelectObject(dcmem.m_hDC,hold); delete pData; DeleteObject(hbmp); CString sos; //测试输出像素数组之一 sos.Format("%d",pData[1]); AfxMessageBox(sos);}开了个20分的帖子,没人理= =如果这个有高手能解决,两边一起给分~~~
[解决办法]
- C/C++ code
HDC hDc = CreateCompatibleDC(NULL); BYTE *lpvBits = NULL;int nRet;BITMAPINFO bmpInfo;ZeroMemory(&bmpInfo,sizeof(bmpInfo));bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);/* 第一次调用GetDIBits获得bmpInfo */nRet = ::GetDIBits(hDc, sm.hBitmap, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS); if (nRet == 0) { nRet = GetLastError(); TRACE( _T("GetDIBits for bmpInfo failed %d\n"), nRet);}lpvBits= new BYTE[bmpInfo.bmiHeader.biSizeImage];if (NULL == lpvBits) { nRet = -1; TRACE( _T("Allocate memory for lpvBits failed\n"));}nRet = GetBitmapBits(sm.hBitmap,bmpInfo.bmiHeader.biSizeImage,lpvBits);/* 第二次调用GetDIBits获得位图数据 *///nRet = ::GetDIBits(hDc, sm.hBitmap, 0, bmpInfo.bmiHeader.biHeight, lpvBits, &bmpInfo, DIB_RGB_COLORS); if (nRet == 0) { nRet = GetLastError(); TRACE( _T("GetDIBits for lpvBits failed %d\n"), nRet);}//如果是32位位图转换为24位if (bmpInfo.bmiHeader.biBitCount == 32){ for (int iBit = 4 ; iBit < bmpInfo.bmiHeader.biSizeImage; iBit += 4) { memcpy(&lpvBits[iBit-(iBit>>2)],&lpvBits[iBit],3); } memset(&lpvBits[bmpInfo.bmiHeader.biSizeImage/4*3],0,bmpInfo.bmiHeader.biSizeImage/4);}
[解决办法]
wid,hei读图像部分的宽,高,不确定的话,=-1把全部图像数据读入buf
- C/C++ code
int ReadBmp(LPCTSTR fname,int wid,int hei,UINT *buf){ int i,j,k,dx,dy,count,pnum,headersize; CFile file; BITMAPFILEHEADER fileheader; BITMAPINFOHEADER inheader; BYTE *bits,*bitbuf,*tmp; RGBQUAD pall[256]; if(!file.Open(fname,CFile::modeRead) ){memset(buf,0,wid*hei*sizeof(int)); return 0; } file.Read(&fileheader,sizeof(BITMAPFILEHEADER)); file.Read(&inheader,sizeof(BITMAPINFOHEADER)); dx=inheader.biWidth; dy=inheader.biHeight; count=inheader.biBitCount; pnum=inheader.biClrUsed; headersize=fileheader.bfOffBits; if(count==1&&pnum==0) pnum=2; if(count==4&&pnum==0) pnum=16; if(count==8&&pnum==0) pnum=256; if(pnum)file.Read(pall,sizeof(RGBQUAD)*pnum); bits=new BYTE[dx*4]; if(wid<=0)wid=dx; if(hei<=0)hei=dy; if(wid==dx&&hei==dy) bitbuf=(BYTE *)buf; else bitbuf=new BYTE[dx*dy*4]; file.Seek(headersize,CFile::begin); if(count==1) { tmp=bitbuf; for(i=0;i<dy;i++) { file.Read(bits,(dx+31)/32*4); bitbuf=tmp+(dy-i-1)*dx*4; for(j=0;j<(dx+31)/32*4;j++) { for(k=0;k<8;k++) { if(bits[j]&(1<<(7-k))) { *bitbuf++=0; *bitbuf++=0; *bitbuf++=255; *bitbuf++=255; }else { *bitbuf++=255; *bitbuf++=0; *bitbuf++=0; *bitbuf++=255; } } } } bitbuf=tmp; }else if(count==4) { tmp=bitbuf; for(i=0;i<dy;i++) { file.Read(bits,((dx+1)/2+3)/4*4); bitbuf=tmp+(dy-i-1)*dx*4; for(j=0;j<dx;j++) { if(j%2) k=bits[j/2]&0x0f; else k=(bits[j/2]&0xf0)>>4; *bitbuf++=pall[k].rgbBlue; *bitbuf++=pall[k].rgbGreen; *bitbuf++=pall[k].rgbRed; *bitbuf++=255; } } bitbuf=tmp; }else if(count==8) { tmp=bitbuf; for(i=0;i<dy;i++) { file.Read(bits,(dx+3)/4*4); bitbuf=tmp+(dy-i-1)*dx*4; for(j=0;j<dx;j++) { k=bits[j]; *bitbuf++=pall[k].rgbBlue; *bitbuf++=pall[k].rgbGreen; *bitbuf++=pall[k].rgbRed; *bitbuf++=255; } } bitbuf=tmp; }else if(count==24) { tmp=bitbuf; for(i=0;i<dy;i++) { file.Read(bits,(dx*3+3)/4*4); bitbuf=tmp+(dy-i-1)*dx*4; for(j=0;j<dx;j++) { *bitbuf++=bits[j*3]; *bitbuf++=bits[j*3+1]; *bitbuf++=bits[j*3+2]; *bitbuf++=255; } } bitbuf=tmp; }else if(count==32) { tmp=bitbuf; for(i=0;i<dy;i++) { file.Read(bits,dx*4); bitbuf=tmp+(dy-i-1)*dx*4; for(j=0;j<dx;j++) { *bitbuf++=bits[j*4]; *bitbuf++=bits[j*4+1]; *bitbuf++=bits[j*4+2]; *bitbuf++=bits[j*4+3]; } } bitbuf=tmp; } delete bits; file.Close(); if(wid!=dx||hei!=dy) { image_scale(dx,dy,(UINT *)bitbuf,wid,hei,buf); delete bitbuf; } return 1;}