C++釋放Bitmap資源、Image資源


1、將存儲圖片二進制數據Byte數組,轉為Image類型

  (1)Byte[] 存到 IStream 流中(流類似管道):

  IStream* m_pView1 = NULL;

  //申請一塊全局內存緩沖區

  m_hBufView1 = GlobalAlloc(GMEM_MOVEABLE,0);

  //將流與內存緩沖區關聯

  CreateStreamOnHGlobal(m_hBufView1, TRUE, &m_pView1);

  //將Byte[]字節數組寫入到流,其實存到對應關聯的內存

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

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

     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;
    }

 

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

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM