2010-08-18 75 views
3

如何使用CImage從BYTE *數組加載圖像? 我的解決方法,直到現在只是簡單地創建一個臨時文件,但有時候這個操作非常昂貴... 有可能是圖書館,但我不想鏈接到其他圖書館,我所需要的只是獲取圖像大小並有效地顯示到屏幕,是的CImage我需要爲...使用ATL CImage從內存緩衝區加載圖像

P-> pbData是一個BYTE *陣列和p> dwDataLen是保持數組大小

我的代碼一個DWORD:

ATL::CAtlTemporaryFile TempFile; 
TempFile.Create(NULL, GENERIC_WRITE | GENERIC_READ); 
TempFile.Write(p->pbData, p->dwDataLen); 
TempFile.HandsOff(); 
ATL::CImage m_image; 
m_image.Load(TempFile.TempFileName()); 
    TempFile.Close(); 
int h = m_image.GetHeight(); 
int w = m_image.GetWidth(); 
// rest of code here 

    m_image.Destroy(); 
m_image.ReleaseGDIPlus();` 

回答

2

你可以用CImage :: Load(IStream *)函數來做到這一點。你可以從CreateStreamOnHGlobal()獲取IStream,或者創建你自己的。

請注意,使用該文件實際上是最好的解決方案。 CImage創建一個內存映射文件來按需加載圖像中的像素。當你從內存加載時,你需要加倍的內存,你會對分頁文件施加壓力。如果圖像很大,你會遇到麻煩。

3
bool Create(BYTE* heap, DWORD heap_len, CImage& img) 
{ 
    bool ret = false; 
    HGLOBAL hGlobal = ::GlobalAlloc(GHND, heap_len); 
    LPBYTE lpByte = (LPBYTE)::GlobalLock(hGlobal); 
    CopyMemory(lpByte, heap, heap_len); 
    ::GlobalUnlock(hGlobal); 
    IStream* pStream = NULL; 
    if (SUCCEEDED(::CreateStreamOnHGlobal(hGlobal, FALSE, &pStream))) 
    { 
     img.Destroy(); 
     img.Load(pStream); 
     pStream->Release(); 
     ret = true; 
    } 
    GlobalFree(hGlobal); 
    return ret; 
} 
0
HRESULT Load(
    IStream* pStream 
) throw(); 

pStream 一個指針,指向包含名的圖像文件加載的流。

所以上述解決方案不能工作,除非堆緩衝區包含文件路徑..;)

+1

首先,它不是一個有效的答案。然後,您所指的方法是在內部調用['GdiPlus :: Bitmap'](https://msdn.microsoft.com/zh-cn/library/ms536319)構造函數,它確實需要流,而不僅僅是文件名。 – 2016-03-01 15:46:55