GDI+中有趣的问题还是很多的,最近碰到关于Gdiplus::Image::FromFile函数的一个问题。
Image类的FromFile函数提供了加载图片的功能,支持很多类型的图片,用起来非常方便。但是我发现在Debug模式下用这个函数加载png格式的图片时会非常慢,在我的机器上(配置还是不错的),加载一个50×40尺寸的png图片,竟然需要188ms;而在Release模式下时间几乎可以忽略不计。
具体原因不明,难道Debug模式下需要做很多验证有效性之类的工作,从而影响了效率?或是Debug下的文件操作或者内存操作导致的?没有找到相关资料,只给出解决办法吧。因为在Debug下调试的时候,如果要加载大量图片文件,那将是一个非常漫长的过程,对调试者来说也算是一个折磨。
我们用另一种图片加载方式来代替FromFile,先将文件数据读到内存中,然后用FromStream从内存中加载图片。代码如下:
HANDLE handle = ::CreateFile(lpszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if( handle == INVALID_HANDLE_VALUE)
return NULL;
DWORD dwSize = ::GetFileSize(handle, NULL);
HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, dwSize);
LPVOID lpBuf = ::GlobalLock(hMem);
DWORD dwRead = 0;
if( ! ::ReadFile(handle,lpBuf, dwSize, &dwRead, NULL))
{
::CloseHandle(handle);
::GlobalUnlock(hMem);
return NULL;
}
::CloseHandle(handle);
IStream* pStream = NULL;
HRESULT hr = ::CreateStreamOnHGlobal(hMem, TRUE, &pStream);
if(FAILED(hr))
{
::GlobalUnlock(hMem);
return NULL;
}
::GlobalUnlock(hMem);
Image* pImg = Gdiplus::Image::FromStream(pStream);
在Debug模式下,用这个方法加载同样的图片只需要47ms,比直接用FromFile快了4倍。
当然,我们可以只在Debug模式下用这种方法,在Release模式下直接调用FromFile。只需要定义一个自己的加载函数LoadImageFromFile,实现如下:
static Image* LoadImageFromFile(LPCTSTR lpszFileName)
{
#ifdef _DEBUG
... // from stream
#else
... // from file
#endif
}