24bits BMP文件前54个字节是头,然后是图像数据:
RGBRGB........  //图像最下面一行的数据,每三个字节一像素,并且每行的长度是4bytes整数倍,就是DIB结构数据区的开始,用读memory或file的方式依次拿到R、G、B数据
RGBRGB........  //图像倒数二行数据.....
.......         //一直到第一行数据结束gray=0.3*r+0.59*G+0.11*b是根据人眼对RGB不同的敏感度转为Gray的,公式不固定。

解决方案 »

  1.   

    Searph,你好,多谢你的解释,但我现在使用的是DIBlook,我不知开始怎样定义一些量,使我能够写到下步:
    for(int x=0;x<width;x++)
    for(int y=0;y<Heigh;y++){
    R=.....?
    G=...?
    b=....?
    gray[x][y]=0.3*r+0.59*G+0.11*b;怎样将之定义为数组?
    }
    十分感谢!
      

  2.   

    我写了一下,没调,你看懂意思就行了,错误自己改改:假如数据区指针是lpRGBData,width、Height是图像宽高(以象素为单位),最好是另外开一块内存存放灰度图像数据,分配内存地址是lpGrayData,两个指针指向内存大小一样。int iRawCount = (width * 3 + 3) / 4 * 4; //计算每行有多少字节,4bytes boundaryfor(int x=0;x<width;x++)
    for(int y=0;y<Heigh;y++)
    {
    R = *(lpRGBData + iRawCount * Height + x * 3);
    G = *(lpRGBData + iRawCount * Height + x * 3 + 1);
    B = *(lpRGBData + iRawCount * Height + x * 3 + 2);Gray = 0.3 * R + 0.59 * G + 0.11 * B;*(lpGrayData + iRawCount * Height + x * 3) = 
    *(lpGrayData + iRawCount * Height + x * 3 + 1) = 
    *(lpGrayData + iRawCount * Height + x * 3 + 2) = Gray;//gray[x][y]=0.3*r+0.59*G+0.11*b;怎样将之定义为数组?
    }
      

  3.   

    Searph,我正在调,希望你斩时别下机,等我的调试消息,我的Email:
    [email protected]
    thank you very much.
      

  4.   

    Searph,lpRGBData 是在CDib中吗?我怎么找不到?iRawCount = (width * 3 + 3) / 4 * 4; 为什么/ 4 * 4,那不是未变么?thank you.
      

  5.   

    不是那么简单的,如果一行不是4字节的整数倍会有对齐字节,直到一行是4字节的整数倍,所以要先算一下是否有对齐字节,有的话要,把这些字节忽略!否则你的位图可能是斜向左的!
    --------
    typedef struct 
    {
     BYTE R;
     BYTE G;
     BYTE B;
    }BITS;
    BITS bits
    int al = width*3/4;
    for(int x=0;x<=width;x++)
    for(int y=0;y<Heigh;y++)
    {
       if(x==width)
       {
         if(al)
           //文件Seek al个字节
       }
      else
    {
         //文件读bits
    //因为位图是从最后一行开始存的,所以:你要
     gray[x][Heigh-y-1] = 0.3*r+0.59*G+0.11*b;
    }
    }
      

  6.   

    我不知道CDib是什么,我没看DIBLOOK那个例子,你应该知道指向图像数据的指针吧。/ 4 * 4会变的,因为取正,例如9 / 4 * 4 = 8,这就完成了4bytes boundary.
    to adrianx:4bytes boundary我已经注意了,int iRawCount = (width * 3 + 3) / 4 * 4; 就是因为这个,例如,width = 1,数据3个bytes,应该占用4bytes,你算一下就知道了,另外,你拿到的数据还是要用来显示,不必把它颠倒过来。
      

  7.   

    adrianx(刘金鑫),Searph is right,thank you for the addition. it seems the m_pBits as lpRGBData ,but it can't get the R,G,B,I don't know why?
      

  8.   

    void CDibView::ColorToGray()
    {
    CDC *pDC=GetDC();
    CDibDoc* pDoc = GetDocument();
    CString str;
    int cxDIB,cyDIB;
    int R,G,B;
    cxDIB=(int)pDoc->Width();
    cyDIB=(int)pDoc->Height();
        int iRawCount = (cxDIB * 3 + 3) / 4 * 4; 
    for(int x=0;x<cxDIB;x++)
    for(int y=0;y<cyDIB;y++){
    R = *(bitmap.m_pBits + iRawCount * cyDIB + x * 3);//I define the (CDib bitmap) in CDibView.h 
        G = *( bitmap.m_pBits+ iRawCount * cyDIB+ x * 3 + 1);
        B = *(bitmap.m_pBits + iRawCount * cyDIB + x * 3 + 2);
        I[x][y] = 0.3 * R + 0.59 * G + 0.11 * B;
    }
    }
    but it can't get the R,G,B?
      

  9.   

    补充一点:
    24位DIB在内存中是按BGR顺序存储的。
    所以上面的程序的顺序要颠倒一下
      

  10.   

    我上面的程序无法得到R, G, B值,可能是bitmap.m_pBits 不是指向图象数据的指针,那一个是呢?用过此类的朋友请告知我,全分奉送。多谢!
      

  11.   

    不要用CDib了,自己写用不了几十行。
      

  12.   

    我在MSDN中都找不到CDib类,找不到CDib类说明,不知道m_pBits是什么,你可以用UE打开你要用DIBLOOK打开的图片,看看那个指针里面的是数据。另外,rocks_lee说的正确,应该是BGRBGR.....,我写反了~
      

  13.   

    thank for reply the question.I think I will pass the trouble.the last question:
    How do I give you the score.It seems no place do I knock or enter.