首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

100求教~怎么将指定位置的bmp图片像素值保存到一个数组中

2012-05-05 
100求教~~如何将指定位置的bmp图片像素值保存到一个数组中?如题,想要设计一个按钮,按下以后,就可以读取硬

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;} 

热点排行