日期:2014-05-18  浏览次数:21868 次

MarShal.Copy
为什么用MarShal.Copy时,我传Byte[]类型可以,用float[]就不可以了呢?
附代码:
  int iWidth = col;
  int iHeight = row;

  Bitmap Result = new Bitmap(iWidth, iHeight, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
  Rectangle rect = new Rectangle(0, 0, iWidth, iHeight);
   
  System.Drawing.Imaging.BitmapData bmpData = Result.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);

  IntPtr iPtr = bmpData.Scan0;

  int iStride = bmpData.Stride;
  int offset = iStride - iWidth;
  int iBytes = iWidth * iHeight;
  int posScan = 0;
  int posReal = 0;

  float[] PixelValues = new float[iBytes];//byte[] pixelValues = new byte[scanBytes]; 

  //System.Runtime.InteropServices.Marshal.Copy(iPtr, PixelValues, 0, iBytes);

  for (int i = 0; i < col ; i++) 
  {
  for (int j = 0; j < row; j++)
  {
  PixelValues[posScan++] = arr[posReal++];//byte 0~255 有负值 
  }
  posScan += offset;
  }

  System.Runtime.InteropServices.Marshal.Copy(PixelValues, 0, iPtr , iBytes);//报错!尝试读取或写入受保护的内存。这通常指示其他内存已损坏
  Result.UnlockBits(bmpData);

------解决方案--------------------
直接原因是一个float占4个bytes。
Marshal.Copy(iPtr, PixelValues, 0, iBytes);
将要求拷贝4*iBytes的字节,而iPtr无法提供。

另:
1、int iBytes = iWidth * iHeight;有误,没有考虑对齐因素。
2、Marshal.Copy(iPtr...有误,iPtr不一定总是指向数据头,也可能指向最后一行。