我必须使用第三方本机API,它将指向BITMAPINFOHEADER结构的指针和指向位图数据的指针作为参数。
static Image load ( IntPtr bi, IntPtr img, string name )
从中指定位图图像构造图像表示 记忆。 bi指针指向BITMAPINFOHEARER,后跟一个 可选颜色表。 colortable的存在取决于 图像类型。字节指针必须指向位图数据,如上所述 通过位图信息。
如何在C#中获取指向具有指定大小的未压缩24位RGB位图的结构指针?
我从这里下载了BITMAPINFOHEADER结构C#decalaration:http://www.pinvoke.net/default.aspx/Structures/BITMAPINFOHEADER.html
我实际上正在使用EmguCV图像类,我试图让BITMAPINFOHEARER描述来自Image<Rgb, byte>
的图像。
var image = new Image<Rgb, byte>(@"myImage.bmp");
//1. create BITMAPINFOHEADER instance
var bitmapInfoHeader = new BITMAPINFOHEADER
{
biSize = (uint)Marshal.SizeOf(typeof(BITMAPINFOHEADER)), //40
biWidth = image.Width, //4096
biHeight = image.Height, //4096
biPlanes = 1,
biBitCount =24,
biCompression = BitmapCompressionMode.BI_RGB,
biSizeImage = (uint)image.Bytes.Length,
};
//2. get pointer to the data
IntPtr ptrData;
fixed (byte* pData = image.Data)
ptrData = (IntPtr)pData;
//3. get pointer to the BitmapInfoHeader:
int iSizeOfBih = Marshal.SizeOf(typeof(BITMAPINFOHEADER));
IntPtr ptrBih = Marshal.AllocHGlobal(iSizeOfBih);
Marshal.StructureToPtr(bih, ptrBih, false);
fixed (byte* pData = image.Bytes)
{
var frImage = Bmp.load(pBitmapInfoHeader, (IntPtr)pData, "Frame");
var faces = faceTracker.processFrame(frImage);
}
虽然这个编译和运行没有异常,但它没有正确加载图像(我以后无法处理使用facetracker。当我使用另一种方法从facetracker工作的文件加载图像时)
我做错了什么?
答案 0 :(得分:0)
回顾评论
有关如何填充BITMAPINFOHEADER
的大部分信息都可以在msdn documentation找到。
应该纠正的一些要点:
biSize
应填充BITMAPINFOHEADER
的大小。此字段在这里是因为结构可以是更完整的版本,如BITMAPV5HEADER
,因此如果设置不正确,它可能会起作用,但显然不建议这样做。
biCompression
应设为BI_RGB
。 BI_BITFIELDS
未记录为24位模式有效
如果图像是自上而下的,则应将biHeight
设置为负值,这可能就像您的情况中的内存表示一样。如果没有,图像可能会被颠倒加载
biSizeImage
似乎设置正确,但由于允许在BI_RGB
模式下将其填充为0,因此可以防止出错。
此外,固定指针(带fixed
)的所有用法都应在fixed
范围内完成。如果在室外使用,则无法保证阵列不会移动到其他位置。
关于维度,Image
类似乎使用行填充,即,如果行的宽度不是4个字节的倍数,则用其他字节填充行。 BITMAPINFOHEADER
描述的位图也应该具有此属性,因此可以期望load
适用于所有维度,但如果load
实际上不支持行填充,则可能需要复制图像到具有精确尺寸的数组。另一种解决方案是在任何地方使用32位模式(并且它也可以提高性能)。