C# Marshal.copy从bitmap.scan0复制到float[]
我正在尝试将托管位图复制到非托管浮点数组(用于Opencl.net包装器的Cl.CreateImage2D)。不幸的是,我得到了一个异常,但是如果我将数组长度(srcIMGBytesSize)除以4,我就成功了。我的数组长度有问题吗?图像格式为32bppargb。我用的是单声道C# Marshal.copy从bitmap.scan0复制到float[],c#,bitmap,mono,marshalling,C#,Bitmap,Mono,Marshalling,我正在尝试将托管位图复制到非托管浮点数组(用于Opencl.net包装器的Cl.CreateImage2D)。不幸的是,我得到了一个异常,但是如果我将数组长度(srcIMGBytesSize)除以4,我就成功了。我的数组长度有问题吗?图像格式为32bppargb。我用的是单声道 System.Drawing.Bitmap bmpImage = new System.Drawing.Bitmap(inputImage); bitmapData = bmpImage.LockBits( new Re
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)
谢谢大家! 请从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);
非常感谢,这很有道理@Ilya:如果使用堆栈上的指针,如果不安全,可能会跳过最后3行。还有一个问题-如何将最终数组转换为IntPtr?所以基本上我要做的是将bitmapData.scan0从指向byte[]的指针转换为指向float[]的指针。检查堆栈,您应该只创建floatArray的数组。长度*4