簡體   English   中英

從bitmap.scan0到float []的Marshal.copy

[英]Marshal.copy from bitmap.scan0 to float[]

我正在嘗試將托管位圖復制到非托管浮點數組(用於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)

謝謝!

從MSDN查看此鏈接

非托管的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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM