0

マネージド ビットマップをアンマネージド 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)

ありがとうございました!

4

1 に答える 1

2

MSDN からこのリンクをチェックしてください

アンマネージの C スタイルの配列には境界情報が含まれていないため、startIndex パラメーターと length パラメーターが検証されません。したがって、ソース パラメーターに対応するアンマネージド データは、その有用性に関係なくマネージド配列に入力されます。このメソッドを呼び出す前に、マネージド配列を適切なサイズで初期化する必要があります。

基本的に、バイト配列を float 配列にコピーしようとしています。各 float (Single) のサイズは 4 バイトであるため、アンマネージ配列からの各 4 バイトは、Marshal.Copy を使用して 1 つの float 値に格納されます。これを確認できます。次のコードを実行します。

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);
于 2012-11-28T13:04:42.423 に答える