C++释放Bitmap资源、Image资源

一、将存储图片二进制数据Byte数组,转为Image类型数组

  (1)Byte[] 存到 IStream 流中(流相似管道):函数

  IStream* m_pView1 = NULL;this

  //申请一块全局内存缓冲区spa

  m_hBufView1 = GlobalAlloc(GMEM_MOVEABLE,0);指针

  //将流与内存缓冲区关联orm

  CreateStreamOnHGlobal(m_hBufView1, TRUE, &m_pView1);对象

  //将Byte[]字节数组写入到流,其实存到对应关联的内存继承

  LARGE_INTEGER zero = {0};
     ULARGE_INTEGER len = {0};图片

  m_pView1->Seek(zero, STREAM_SEEK_SET, NULL);ip

     m_pView1->Write(字节数组首址,图片数据字节数,NULL);

  //得到写入流中数据长度

     m_pView1->Seek(zero, STREAM_SEEK_CUR, &len);

  DWORD dwlPic1 = len.LowPart;

  //从新定位到IStream头
     m_pView1->Seek(zero, STREAM_SEEK_SET, NULL);


       if(dwlPic1 !=0)
    {

      //Byte[]转为IStream成功,若Byte[]是new出来的,这时Byte[]所占用内存能够释放    

    }

  (2)将IStream转为Image

  Image* imgV1 = Image::FromStream(m_pView1);

  /* Image::FromStream(){  

    new Image(m_pView1,false)

    {

        //GpImage* nativeImage 为Image成员变量,存储图片数据

        //nativeImage进入是野指针,出来时指向存放图片数据的内存

        DllExports::GdipLoadImageFromStream(m_pView1,&nativeImage);  //将图片保存到Image类中nativeImage变量上

    };   

  } */

  //Image::FromStream()静态方法中new了一个Image对象,因此在外部不适用imgV1时,就释放它

  (3)释放Image资源

  delete imgV1;

  /* Image::~Image()

  {

     DllExports::GdipDisposeImage(nativeImage);    //释放nativeImage存储图片数据占用的内存

  }*/

  (4)IStream不使用,释放内存

   if(m_pView1 != NULL)
    {
      m_pView1->Release();
      GlobalFree(m_hBufView1);
      m_pView1 = NULL;
    }

 

二、释放Bitmap资源

  在GDI+类库中对Bitmap类定义。

  Bitmap类继承自Image类,且Bitmap没有定义析构函数,为默认析构函数

  (1)建立Bitmap对象

  Bitmap bmp(width,height,PixelFormat24bppRGB);

  /* 内部 {

    GpBitmap *bitmap = NULL;    //GpBitmap继承自GpImage,存储图片数据

    //建立一块能够存储24位位图格式的内存,取得内存地址bitmap

      lastResult = DllExports::GdipCreateBitmapFromScan0(width,
                                                       height,
                                                       0,
                                                       format,
                                                       NULL,
                                                       &bitmap);

    //将存储位图数据的内存地址保存到成员变量 nativeImage 中

        SetNativeImage(bitmap);    // {  this->nativeImage = bitmap  }

  } */

  (2)释放Bitmap对象

  这时咱们发现对于Image对象,它有析构函数内存释放nativeImage所存储图片的内存,不会形成内存泄露

  而Bitmap没有定义析构函数,采用默认析构函数,那Bitmap构造出来的内存没法释放,会形成内存泄露

  (固然对于C#、VB对GDI+库有响应的方法释放内存)

  这时候咱们能够参考父类Image的析构函数显式的释放nativeImage所占用内存空间

  DllExports::GdipDisposeImage(nativeImage);

  //nativeImage不是public,能够在Image类中定义一个函数GetnativeImage

  

小结:

  因为nativeImage从Image类中继承过来的,在Bitmap构造的时候赋值内存首址

  因此析构的时候Bitmap析构没释放,可能会在Image析构中释放,这个也可能不会释放,从而致使使用Bitmap越多,内存占用越大的状况

  对于内部申请内存的API或者方法,在外部要记得释放内存