GetBitmapBits和GetDibits函数得到的图像数据的顺序是相反的

   http://www.cnblogs.com/lzjsky/archive/2010/08/08/1795129.html
      Windows GDI中有两个用来得到位图图像数据的API,分别是GetDIBits和GetBitmapBits;按照MSDN的解释,前者是用来得到设备独立位图的BITS,后者是得到兼容位图的BITS,所以在调用该函数的时候,第一个主要的区别是:GetBitmapBits需要提供一个设备内容,同时需要将位图的HANDLE选进这个设备内容(DC)才能能够得到位图的信息。
   我想上面的区别大家可能都知道,其实它还隐藏着另一个区别:就是对于同一个位图,得到的BITS内容的BUFFER不一样!
   大家都知道BMP文件存储数据是倒叙,也就是从图像的右下角开始存储,文件的最后是图像的左上角(这个来历可以看:WINDOWS编程中介绍);使用GetBitmapBits取得的BUFFER,位图的右下角的内容为第一个字节,实际上和真正的图像字节应该是一样的,而GetDIBits刚好相反,其BUFFER的顺序符合BMP文件中的顺序,如果按照正常的坐标,其存储顺序应该是倒叙
   所以在程序中要合理的使用这两个API来得到你想要的位图数据。
   !!!----这也是为何在 BOOL CAviapi::GetAviFrame(DWORD Index, HDC hdc, int x, int y, int cx, int cy, int ox, int oy, double scale)
             中使用  StretchDIBits(hCacheDC, 0, 0, m_FrameWidth, m_FrameHeight,
                     0, 0, m_FrameWidth, m_FrameHeight,
                     (LPBYTE)(lpImage) + ImageStart,
                     (BITMAPINFO*)lpImage, 0, SRCCOPY);
                     向DC绘制,而不是直接将内存数据通过CBitmap::SetBitmapBits 写入位图的原因(---可能可以考虑用::SetDIBits--不过这里需要拉伸,所以用 StretchDIBits, )
                    
      !!!---GetBitmapBits是设备相关,使得你的程序很难维护,其实GetDibits一样可以得到从左到右从上到下的数据。
      只要吧传入GetDibits中的BITMAPINFO结构的成员
      BmpInfo.bmiHeader.biHeight=-Bmp.bmHeight'这与GDI的坐标系统相反,为方便,
      '改为-值,则取得数据就是以左上角为起点
      就一样了。
原文地址:https://www.cnblogs.com/carl2380/p/2011479.html