我有代码,将PNG资源转换为GdiPlus::Bitmap
并绘制它。
void ResBit(HINSTANCE hInstance,HDC hdcC,HWND hwnd, char *Name, int x,int y,int cx,int cy)
{
spe sp;
sp.h=hInstance;
sp.name=Name;
static int save[1000][3]={NULL};
static int count=0;
int current;
for(int i(0);i<=count;i++)
{
if(save[i][0]==(int)hInstance&&save[i][1]==(int)Name)
{
current=i;
break;
}
if(i==count)
{
if (HRSRC resource = ::FindResourceA(hInstance, Name, "PNG"))
if (DWORD size = ::SizeofResource(hInstance, resource))
if (const void* data = ::LockResource(::LoadResource(hInstance, resource)))
if (HGLOBAL handle = ::GlobalAlloc(GMEM_MOVEABLE, size)) {
if (void* buffer = ::GlobalLock(handle)) {
CopyMemory(buffer, data, size);
IStream* stream = NULL;
if (::CreateStreamOnHGlobal(handle, FALSE, &stream) == S_OK)
{
if (Bitmap* bitmap =
Bitmap::FromStream(stream))
{
if (bitmap->GetLastStatus() == Gdiplus::Ok) {
save[i][0]=(int)hInstance;
save[i][1]=(int)Name;
save[i][2]=(int)bitmap;
current=i;
count++;
break;
}
}
stream->Release();
}
GlobalUnlock(handle);
}
}
}
}
RECT r;
GetClientRect(hwnd,&r);
Graphics g(hdcC);
if(!cx)
g.DrawImage((Bitmap*)save[current][2],0,0,r.right,r.bottom);
else
g.DrawImage((Bitmap*)save[current][2],x,y,cx,cy);
}
所以当出现HINSTANCE并命名时,请检查static
数组save
是否有相同的数据。如果是,则返回Bitmap
。如果不是,它会找到新资源,创建新的Bitmap
并将数据添加到数组中。在使用Graphics::DrawImage
检查绘图后。麻烦就是速度。它绘制得非常慢。我尝试将GdiPlus::Bitmap
转换为HBITMAP
,但遭遇了挫折。
怎么样?我需要快速画画。
答案 0 :(得分:0)
static int save[1000][3]={NULL};
...
save[i][2]=(int)bitmap;
您无法强制所有内容转换为整数并返回其他数据类型。如果您开始使用Unicode函数,也可以避免很多问题。
Gdiplus::Bitmap *loadpng(HINSTANCE hInstance, const wchar_t* Name)
{
Gdiplus::Bitmap *result = NULL;
HRSRC resource = ::FindResourceW(hInstance, Name, L"PNG");
if (resource)
{
DWORD size = ::SizeofResource(hInstance, resource);
if (size)
{
LPVOID data = ::LockResource(::LoadResource(hInstance, resource));
if (data)
{
HGLOBAL handle = ::GlobalAlloc(GMEM_MOVEABLE, size);
if (handle)
{
void* buffer = ::GlobalLock(handle);
if (buffer)
{
CopyMemory(buffer, data, size);
IStream* stream = NULL;
if (::CreateStreamOnHGlobal(handle, FALSE, &stream) == S_OK)
{
if (Gdiplus::Bitmap* bitmap = Gdiplus::Bitmap::FromStream(stream))
{
if (bitmap->GetLastStatus() == Gdiplus::Ok)
{
result = bitmap;
}
}
stream->Release();
}
}
GlobalUnlock(handle);
}
}
}
}
return result;
}
用法:
Gdiplus::Bitmap* bitmap = loadpng(hInstance, L"RESOURCE_ID"); //or MAKEINTRESOURCE...
Gdiplus::Graphics g(hdc);
g.DrawImage(bitmap, x, y, w, h);
如果这个功能很慢那么就是这样。应用程序一次最多可以使用10,000个资源。如果有数千张图像并达到10,000限制,则应用程序可能会减速停止。
您可能希望使用容器来避免每次都加载图像(但每次调用只会节省几微秒)。例如:
#include <map>
#include <string>
...
void ResBit(HINSTANCE hInstance, HDC hdc, wchar_t *Name, int x, int y, int w, int h)
{
static std::map<std::wstring, Gdiplus::Bitmap*> map;
if (!map.count(Name))
map[Name] = loadpng(hInstance, Name);
Gdiplus::Bitmap* bitmap = map[Name];
if (!bitmap)
return;
Gdiplus::Graphics g(hdc);
g.DrawImage(bitmap, x, y, w, h);
}