记忆中获取dib位图是有顺序一说的,,,今天被坑了一把确实是有一说,是和图像的格式相关的,MSDN上这样描述:
“
A pointer to the bitmap buffer. If the bitmap is a bottom-up DIB, the pointer points near the end of the buffer. If the bitmap is a top-down DIB, the pointer points to the first byte of the buffer.
”
摘录网上查到的笔记:
“
CImage类提供了GetBits()函数来读取数据区,GetBits()函数返回的是图片最后一行第一个像素的地址,网上有人说返回指针的起始位置是不同的,有些图片返回的是左上角像素的地址,有些是左下角像素的地址,跟图片内部顺序有关。这里我们不必关心起始位置,只要很另外两个函数GetPitch()和GetHeight()一起使用就可以得到图片数据取得起始位置,定义数据区指针为BYTE* img_Data
img_Data=(BYTE *)m_Image.GetBits()+(m_Image.GetPitch()*(m_Image.GetHeight()-1));
这样,img_Data就是图片数据区的起始位置,这个公式是从codeproject里看到的,介绍的很精辟,可以从google里搜索到。其中GetHeight()函数返回图片的高度(以像素为单位)。GetPitch()返回图像的斜度,如果图像的顺序是从下到上(也就是GetBits()返回左上角像素的地址),这时GetPitch()返回一个负值,大小为图像宽所占有的字节数,例如24位800*600的图片,返回值应该是正或负的800*3。这样用每一行的字节数乘行数就可以得到起始位置了。
”
以上是使用CImage获取的时候遇到的坑爹,相信直接使用位图相关的api也是一样,msdn描述:
Device-Independent Bitmaps
There are two varieties of DIBs:
- A bottom-up DIB, in which the origin lies at the lower-left corner.
- A top-down DIB, in which the origin lies at the upper-left corner.
使用gdiplus的时候BitmapData也是类似:
Stride
INT
Offset, in bytes, between consecutive scan lines of the bitmap. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up.
两个关键属性:
GetPitch( )
Stride
还有泥马一个被微软坑了的坏习惯,DWORD用习惯了,调试了一天都没看出来这两个值我取到的是负的,,,坑啊,,,