0

我正在尝试将托管位图复制到非托管浮点数组(用于 Opencl.net 包装器的 Cl.CreateImage2D)。不幸的是,我遇到了一个异常,但是如果我将数组长度 (srcIMGBytesSize) 除以 4,我就成功了。我的数组长度有问题吗?图像格式为 Format32bppArgb。我正在使用单声道。

System.Drawing.Bitmap bmpImage = new System.Drawing.Bitmap(inputImage);
bitmapData = bmpImage.LockBits( new Rectangle(0, 0, bmpImage.Width, bmpImage.Height), ImageLockMode.ReadOnly, inputImage.PixelFormat);
IntPtr srcBmpPtr = bitmapData.Scan0;
int bitsPerPixel = Image.GetPixelFormatSize( inputImage.PixelFormat );
srcIMGBytesSize = bitmapData.Stride * bitmapData.Height;
float[] srcImage2DData = new float[srcIMGBytesSize];
Marshal.Copy(srcBmpPtr, srcImage2DData, 0, srcIMGBytesSize);   //Exception at this line
bmpImage.UnlockBits( bitmapData );

尝试将数据复制到 float[] 数组时出现以下异常:

System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception.
   at System.Runtime.InteropServices.Marshal.CopyToManaged(IntPtr source, Object destination, Int32 startIndex, Int32 length)
   at System.Runtime.InteropServices.Marshal.Copy(IntPtr source, Single[] destination, Int32 startIndex, Int32 length)

谢谢!

4

1 回答 1

2

从 MSDN查看此链接

非托管的 C 样式数组不包含边界信息,这会阻止验证 startIndex 和 length 参数。因此,对应于源参数的非托管数据会填充托管数组,而不管其有用性如何。在调用此方法之前,您必须使用适当的大小初始化托管数组。

基本上,您正在尝试将字节数组复制到浮点数组,每个浮点(单)的大小为 4 个字节,因此,非托管数组中的每四个字节将使用 Marshal.Copy 存储在一个浮点值中,您可以检查一下通过执行以下代码:

byte[] byteSrcImage2DData = new byte[srcIMGBytesSize];
Marshal.Copy(srcBmpPtr, byteImage2DData, 0, srcIMGBytesSize);

它之所以有效,是因为整个源数组将使用目标数组的所有字段,这与您第一次尝试仅使用第一季度不同。

您可以使用此代码解决您的问题。您可以先将非托管数组复制到字节数组,然后可以将字节数组复制到浮点数组:

System.Drawing.Bitmap bmpImage = new System.Drawing.Bitmap(inputImage);
BitmapData bitmapData = bmpImage.LockBits(new Rectangle(0, 0, bmpImage.Width, bmpImage.Height), ImageLockMode.ReadOnly, inputImage.PixelFormat);
IntPtr srcBmpPtr = bitmapData.Scan0;
int bitsPerPixel = Image.GetPixelFormatSize(inputImage.PixelFormat);
int srcIMGBytesSize = bitmapData.Stride * bitmapData.Height;
byte[] byteSrcImage2DData = new byte[srcIMGBytesSize];
Marshal.Copy(srcBmpPtr, byteSrcImage2DData, 0, srcIMGBytesSize);
float[] srcImage2DData = new float[srcIMGBytesSize];
Array.Copy(byteSrcImage2DData, srcImage2DData,srcIMGBytesSize);   //Exception at this line
bmpImage.UnlockBits(bitmapData);
于 2012-11-28T13:04:42.423 回答