C# Marshal.StructureToPtr Sizeof AllocHGlobal的思考 与 数据绑定空间picturebox 的实战

版权声明:欢迎转载与留言提问 https://blog.csdn.net/qq_25439417/article/details/81909484
public GxBitmap(IGXDevice objIGXDevice, PictureBox objPictureBox)
      {
          m_objIGXDevice = objIGXDevice;
          m_pic_ShowImage = objPictureBox;
          string strValue = null;
          if (null != objIGXDevice)
          {
              //获得图像原始数据大小、宽度、高度等
              m_nPayloadSize = (int)objIGXDevice.GetRemoteFeatureControl().GetIntFeature("PayloadSize").GetValue();
              m_nWidth = (int)objIGXDevice.GetRemoteFeatureControl().GetIntFeature("Width").GetValue();
              m_nHeigh = (int)objIGXDevice.GetRemoteFeatureControl().GetIntFeature("Height").GetValue();

              //获取是否为彩色相机
              if (objIGXDevice.GetRemoteFeatureControl().IsImplemented("PixelColorFilter"))
              {
                  strValue = objIGXDevice.GetRemoteFeatureControl().GetEnumFeature("PixelColorFilter").GetValue();

                  if ("None" != strValue)
                  {
                      m_bIsColor = true;
                  }
              }
          }

          //申请用于缓存图像数据的buffer
          m_byRawBuffer = new byte[m_nPayloadSize];
          m_byMonoBuffer = new byte[__GetStride(m_nWidth, m_bIsColor) * m_nHeigh];
          m_byColorBuffer = new byte[__GetStride(m_nWidth, m_bIsColor) * m_nHeigh];

          __CreateBitmap(out m_bitmapForSave, m_nWidth, m_nHeigh, m_bIsColor);

          m_objGC = m_pic_ShowImage.CreateGraphics();
          m_pHDC = m_objGC.GetHdc();
          if (m_bIsColor)
          {
              m_objBitmapInfo.bmiHeader.biSize = (uint)Marshal.SizeOf(typeof(CWin32Bitmaps.BITMAPINFOHEADER));
              m_objBitmapInfo.bmiHeader.biWidth = m_nWidth;
              m_objBitmapInfo.bmiHeader.biHeight = -m_nHeigh;
              m_objBitmapInfo.bmiHeader.biPlanes = 1;
              m_objBitmapInfo.bmiHeader.biBitCount = 24;
              m_objBitmapInfo.bmiHeader.biCompression = 0;
              m_objBitmapInfo.bmiHeader.biSizeImage = 0;
              m_objBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
              m_objBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
              m_objBitmapInfo.bmiHeader.biClrUsed = 0;
              m_objBitmapInfo.bmiHeader.biClrImportant = 0;
          }
          else
          {
              m_objBitmapInfo.bmiHeader.biSize = (uint)Marshal.SizeOf(typeof(CWin32Bitmaps.BITMAPINFOHEADER));
              m_objBitmapInfo.bmiHeader.biWidth = m_nWidth;
              m_objBitmapInfo.bmiHeader.biHeight = -m_nHeigh;
              m_objBitmapInfo.bmiHeader.biPlanes = 1;
              m_objBitmapInfo.bmiHeader.biBitCount = 8;
              m_objBitmapInfo.bmiHeader.biCompression = 0;
              m_objBitmapInfo.bmiHeader.biSizeImage = 0;
              m_objBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
              m_objBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
              m_objBitmapInfo.bmiHeader.biClrUsed = 0;
              m_objBitmapInfo.bmiHeader.biClrImportant = 0;

              m_objBitmapInfo.bmiColors = new CWin32Bitmaps.RGBQUAD[256];
              // 黑白图像需要初始化调色板
              for (int i = 0; i < 256; i++)
              {
                  m_objBitmapInfo.bmiColors[i].rgbBlue     = (byte)i;
                  m_objBitmapInfo.bmiColors[i].rgbGreen    = (byte)i;
                  m_objBitmapInfo.bmiColors[i].rgbRed      = (byte)i;
                  m_objBitmapInfo.bmiColors[i].rgbReserved = (byte)i;
              }
          }
          m_pBitmapInfo = Marshal.AllocHGlobal(2048);
          Marshal.StructureToPtr(m_objBitmapInfo, m_pBitmapInfo, false);
      }

下面这个函数有点意思,C#中通过RGB创建位图的调色板,所以灰度是RGB三色同值的256种情况

private void __CreateBitmap(out Bitmap bitmap, int nWidth, int nHeight, bool bIsColor)
      {
          bitmap = new Bitmap(nWidth, nHeight, __GetFormat(bIsColor));
          if (bitmap.PixelFormat == PixelFormat.Format8bppIndexed)
          {
              ColorPalette colorPalette = bitmap.Palette;
              for (int i = 0; i < 256; i ++)
              {
                  colorPalette.Entries[i] = Color.FromArgb(i, i, i);
              }
              bitmap.Palette = colorPalette;
          }
      }

Marshal.AllocHGlobal之后需要自己释放内存,因为非托管内存属于C#GC范畴之外的数据,GC无法完成自动回收,可以Marshal.FreeHGlobal(ptr);避免溢出

猜你喜欢

转载自blog.csdn.net/qq_25439417/article/details/81909484
今日推荐