2012-11-28 62 views
0

我試圖將託管的位圖複製到非託管的浮點數組(用於Opencl.net包裝的Cl.CreateImage2D)。不幸的是,我得到了一個異常,但是如果我將數組長度(srcIMGBytesSize)除以4,我就成功了。數組的長度有問題嗎?圖像格式是Format32bppArgb。我正在使用單聲道。Marshal.copy from bitmap.scan0 float []

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); 

試圖將數據複製到浮動的時候,我發現了以下異常[]數組:

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) 

謝謝!

回答

2

退房此link從MSDN

非管理型,C型陣列不包含邊界信息,其 防止startIndex和長度參數被驗證。 因此,與源參數 對應的非託管數據將填充託管數組,無論其用途如何。在調用 此方法之前,您必須使用適當的大小初始化託管陣列 。

基本上你正在試圖字節數組複製到一個浮陣列,每個浮子(單)是大小爲4個字節,因此,從非託管陣列中的每個四個字節將被存儲在使用Marshal所述一個浮點值。副本,您可以通過執行以下代碼檢查:

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); 
+0

非常感謝,這使得很有意義! –

+1

@Ilya:如果在棧上使用指針,如果不安全,可能會跳過最後3行。 – leppie

+0

還有一個問題 - 我將如何將最終數組轉換爲IntPtr?所以基本上我想要做的是將bitmapData.scan0從指針轉換爲byte []到指向float []的指針。 –