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或者方法,在外部要記得釋放內存

相關文章
相關標籤/搜索