gdi+的Graphics::DrawImage非常缓慢~~

/* 首先抱歉我的英语不好,而且代码部分是波兰语,但很容易理解。

我曾经遇到同样的问题,现在我找到了最好的解决方案。下面是解决方案。

不要使用:Graphics graphics(hdc); graphics.DrawImage(gpBitmap,0,0); 这样会很慢。

使用:GetHBITMAP(Gdiplus :: Color(),&g_hBitmap)获取 HBITMAP,并使用我的 ShowBitmapStretch()函数进行绘制。

您可以调整大小,并且速度更快!Artur Czekalski / 波兰

*/

//--------Global-----------

Bitmap *g_pGDIBitmap; //for loading picture

int gRozXOkna, gRozYOkna; //size of working window

int gRozXObrazu, gRozYObrazu; //Size of picture X,Y

HBITMAP g_hBitmap = NULL; //for displaying on window

//------------------------------------------------------------------------------

int ShowBitmapStretch(HDC hdc, HBITMAP hBmp, int RozX, int RozY, int RozXSkal, int RozYSkal, int PozX, int PozY)

{

if (hBmp == NULL) return -1;

HDC hdc_mem = CreateCompatibleDC(hdc); //utworzenie kontekstu pamięciowego

if (NULL == hdc_mem) return -2;

//Trzeba połączyć BMP z hdc_mem, tzn. umieścić bitmapę w naszym kontekście pamięciowym

if (DeleteObject(SelectObject(hdc_mem, hBmp)) == NULL) return -3;

SetStretchBltMode(hdc, COLORONCOLOR); //important! for smoothness

if (StretchBlt(hdc, PozX, PozY, RozXSkal, RozYSkal, hdc_mem, 0, 0, RozX, RozY, SRCCOPY) == 0) return -4;

if (DeleteDC(hdc_mem) == 0) return -5;

return 0; //OK

}

//---------------------------------------------------------------------------

void ClearBitmaps(void)

{

if (g_hBitmap) { DeleteObject(g_hBitmap); g_hBitmap = NULL; }

if (g_pGDIBitmap) { delete g_pGDIBitmap; g_pGDIBitmap = NULL; }

}

//---------------------------------------------------------------------------

void MyOpenFile(HWND hWnd, szFileName)

{

ClearBitmaps(); //Important!

g_pGDIBitmap = new Bitmap(szFileName); //load a picture from file

if (g_pGDIBitmap == 0) return;

//---Checking if picture was loaded

gRozXObrazu = g_pGDIBitmap->GetWidth();

gRozYObrazu = g_pGDIBitmap->GetHeight();

if (gRozXObrazu == 0 || gRozYObrazu == 0) return;

//---Uworzenie bitmapy do wyświatlaia; DO IT ONCE HERE!

g_pGDIBitmap->GetHBITMAP(Gdiplus::Color(), &g_hBitmap); //creates a GDI bitmap from this Bitmap object

if (g_hBitmap == 0) return;

//---We need to force the window to redraw itself

InvalidateRect(hWnd, NULL, TRUE);

UpdateWindow(hWnd);

}

//---------------------------------------------------------------------------

void MyOnPaint(HDC hdc, HWND hWnd) //in case WM_PAINT; DO IT MANY TIMES

{

if (g_hBitmap)

{

double SkalaX = 1.0, SkalaY = 1.0; //scale

if (gRozXObrazu > gRozXOkna || gRozYObrazu > gRozYOkna || //too big picture, więc zmniejsz;

(gRozXObrazu < gRozXOkna && gRozYObrazu < gRozYOkna)) //too small picture, można powiększyć

{

SkalaX = (double)gRozXOkna / (double)gRozXObrazu; //np. 0.7 dla zmniejszania; FOR DECREASE

SkalaY = (double)gRozYOkna / (double)gRozYObrazu; //np. 1.7 dla powiększania; FOR INCREASE

if (SkalaY < SkalaX) SkalaX = SkalaY; //ZAWSZE wybierz większe skalowanie, czyli mniejszą wartość i utaw w SkalaX

}

if (ShowBitmapStretch(hdc, g_hBitmap, gRozXObrazu, gRozYObrazu, (int)(gRozXObrazu*SkalaX), (int)(gRozYObrazu*SkalaX), 0, 0, msg) < 0) return;