Creating a Bitmap from an IntPtr
我想知道如何使用USB摄像机API,这有点不太清楚(至少它似乎依赖于开发人员以前的知识,我不认为我理解"整张图片",双关语的意图)。
我有以下成功接收数据的事件处理程序,目前只能打印到控制台:
1 2 3 4 5 6 7 8 9 10 11 12 13 | void _camera_OnPreviewBitmap(IntPtr pbyteBitmap, uint dwBufferSize, uint dwWidth, uint dwHeight, uint dwFrameNo, uint dwPreviewPixelFormat) { Console.WriteLine(string.Format("{0}, {1}, {2}, {3}, {4}, {5}", pbyteBitmap, dwBufferSize, dwWidth, dwHeight, dwFrameNo, dwPreviewPixelFormat)); //The callback function gets the image data as"IntPtr" type. //When using"System.Runtime.InteropServices.Marshal.Copy", the image data can copy to the array. //When using"System.Runtime.InteropServices.Marchal.ReadByte", the image data can get thedirectory. //Sometimes the process speed is fast when receiving the image data after the image data copy to the array with //"System.Runtime.InteropServices.Marchal.Copy". } |
这给了我这些结果:
1 2 3 4 5 6 7 8 9 10 11 12 | 259129344, 1228800, 1280, 960, 195051, 1 250281984, 1228800, 1280, 960, 195052, 1 259129344, 1228800, 1280, 960, 195053, 1 250281984, 1228800, 1280, 960, 195054, 1 259129344, 1228800, 1280, 960, 195055, 1 250281984, 1228800, 1280, 960, 195056, 1 259129344, 1228800, 1280, 960, 195057, 1 250281984, 1228800, 1280, 960, 195058, 1 259129344, 1228800, 1280, 960, 195059, 1 250281984, 1228800, 1280, 960, 195060, 1 259129344, 1228800, 1280, 960, 195061, 1 250281984, 1228800, 1280, 960, 195062, 1 |
号
因此,这与图像尺寸(1280 x 960)是一致的,1228800是像素计数(缓冲区大小),像素格式的
我的问题是:
How can I take this information and create a
System.Drawing.Bitmap object with it?
号
我已经尝试过了,但没有成功(很明显,灰度图像实际上没有索引…):
1 2 | var bmp = new System.Drawing.Bitmap((int)dwWidth, (int)dwHeight, (int)dwBufferSize, PixelFormat.Format8bppIndexed, pbyteBitmap); |
这最终会产生"通用GDI+错误"。
您指定的是索引格式,而不提供调色板。
如果图像是灰度图像,您可以使用32bpp创建位图,锁定位,然后将rgb字节值设置为像素字节数据,而不是直接使用指针,下面是一个示例(使用不安全的代码以方便和快速):
1 2 3 4 5 6 7 8 9 10 11 12 13 | Bitmap bmp = new Bitmap(1280, 960, System.Drawing.Imaging.PixelFormat.Format32bppRgb); var data = bmp.LockBits(new Rectangle(0, 0, 1280, 960), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb); byte* srcBmpData = (byte*)pbyteBitmap.ToPointer(); byte* dstBmpData = (byte*)data.Scan0.ToPointer(); for (int buc = 0; buc < 1280 * 960; buc++) { int currentDestPos = buc * 4; dstBmpData[currentDestPos] = dstBmpData[currentDestPos + 1] = dstBmpData[currentDestPos + 2] = srcBmpData[buc]; } bmp.UnlockBits(data); |