我正在尝试将托管位图复制到非托管浮点数组(用于Opencl.net包装器的Cl.CreateImage2D)。不幸的是我得到了一个异常,但是如果我把数组长度(srcIMGBytesSize)除以4,我就成功了。我的阵列长度有问题吗?图像格式为Format32bppArgb。我正在使用mono。
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)
谢谢!
答案 0 :(得分:2)
从MSDN中查看此link
非托管,C风格的数组不包含边界信息 阻止验证startIndex和length参数。 因此,对应于源参数的非托管数据 无论其有用性如何,都会填充托管数组。你必须 在调用之前使用适当的大小初始化托管数组 这种方法。
基本上你试图将字节数组复制到一个float数组,每个float(Single)的大小为4个字节,因此,非托管数组中的每四个字节将使用Marshal.Copy存储在一个浮点值中,你可以通过执行以下代码来检查:
byte[] byteSrcImage2DData = new byte[srcIMGBytesSize];
Marshal.Copy(srcBmpPtr, byteImage2DData, 0, srcIMGBytesSize);
它的工作原理是因为整个源数组将使用目标数组的所有字段,这与您第一次使用第一季度时不同。
您可以使用此代码解决您的问题。您可以先将非托管数组复制到字节数组,然后将字节数组复制到float数组中:
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);