一、將存儲圖片二進制數據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或者方法,在外部要記得釋放內存