使用ATL CImage从内存缓冲区加载图像

时间:2010-08-18 16:23:30

标签: c++ winapi atl

如何使用CImage从BYTE *数组加载图像? 到目前为止,我的解决方法是简单地创建一个临时文件,但有时这个操作非常昂贵...... 可能有库,但我不想链接到其他库,我只需要获得图像大小并有效地显示到屏幕,而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();` 

3 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:2)

您可以使用CImage :: Load(IStream *)函数执行此操作。您可以从CreateStreamOnHGlobal()获取IStream或创建自己的。

请注意,使用该文件实际上是优秀的解决方案。 CImage创建了一个内存映射文件,用于从图像中加载像素。从内存加载时,你需要加倍内存,你将对页面文件施加压力。如果图像很大,你会遇到麻烦。

答案 2 :(得分:0)

var formSubmit = angular.module('formSubmit', ['app', 'creditor', 'ngFileUpload']);
                                               ^^^^^

HRESULT Load( IStream* pStream ) throw(); 指向包含要加载的图像文件的名称的流的指针。

所以上述解决方案无法正常工作,除非堆缓冲区由文件路径组成..;)