C++ Win32:加速位图操作
C++ Win32: Speeding up Bitmap Operations
我想加快位图显示程序的速度。它并不慢得可怕,我只是认为它可以更快。我运行它在Win32环境下。这是代码:
void load(LPCWSTR file, int i) {
hBitmap[i] = (HBITMAP)::LoadImage(NULL, file, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE);
GetObject(hBitmap[i], sizeof(BITMAP), (LPSTR)&hSize[i]);
}
void newBit(int i, int x, int y, HDC hdc) {
BITMAP Bitmap = hSize[i];
HBITMAP hBit = hBitmap[i];
HDC hDCBits = CreateCompatibleDC(hdc);
SelectObject(hDCBits, hBit);
StretchBlt(hdc, x, y, Bitmap.bmWidth, Bitmap.bmHeight,
hDCBits, 0, 0, Bitmap.bmWidth, Bitmap.bmHeight, SRCCOPY);
DeleteDC(hDCBits);
}
我 运行 一开始就是 "Load" 函数,我对它需要多长时间没有意见。我 运行 在我需要的程序中随时使用 newBit 函数。我特别使用 stretchBlt 命令,因为我需要调整大小的功能。如果能深入了解我做错了什么以及我可以改进什么,我们将不胜感激。
因为我怀疑它与你之前的问题 here 有关系,所以我 post 下面的回答。
如果您想在 window 中创建一些动画并加快速度,请考虑使用 GDI+ 而不是普通的 winapi。
使用 GDI+,您只需将绘图方法放入 WM_PAINT
消息中,并通过使您的控制矩形无效并更新 window.
来更新您的场景
例如:
InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow(hwnd);
WM_PAINT 消息处理可能如下所示:
case WM_PAINT:
{
/************************************************************************/
/* Initialize */
/************************************************************************/
hdc = BeginPaint(hwnd, &ps);
Graphics graphics(hdc);
Bitmap *pMemBitmap = new Bitmap(rect.right, rect.bottom);
Graphics* pMemGraphics = Graphics::FromImage(pMemBitmap);
SolidBrush back(Color(0, 0, 0));
pMemGraphics->FillRectangle(&back, 0, 0, rect.right, rect.bottom); // Fill your background with some color
pMemGraphics->SetSmoothingMode(SmoothingModeHighQuality); // Set your raster quality
graphics.SetSmoothingMode(SmoothingModeHighQuality);
// Rotate some primitive around your screen
static double x = M_PI + M_PI / 2;
x += 0.03f;
if(x > M_PI * 2)
{
x = 0;
}
double posX = cos(x);
double posY = sin(x);
Pen pen(Color(255, 255, 255, 0), 5);
pMemGraphics->DrawEllipse(&pen, (int)(posX * 50 - 15 + rect.right / 2), (int)(posY * 50 - 15 + rect.bottom / 2), 30, 30);
graphics.DrawImage(pMemBitmap, 0, 0); // Draw the entire bitmap to screen (double buffering)
/************************************************************************/
/* Cleanup */
/************************************************************************/
delete pMemGraphics;
delete pMemBitmap;
EndPaint(hwnd, &ps);
break;
}
为了避免闪烁,你应该告诉 winapi 不要像这样擦除背景:
case WM_ERASEBKGND:
{
return true; // Tell winapi, we already handled that.
}
我想加快位图显示程序的速度。它并不慢得可怕,我只是认为它可以更快。我运行它在Win32环境下。这是代码:
void load(LPCWSTR file, int i) {
hBitmap[i] = (HBITMAP)::LoadImage(NULL, file, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE);
GetObject(hBitmap[i], sizeof(BITMAP), (LPSTR)&hSize[i]);
}
void newBit(int i, int x, int y, HDC hdc) {
BITMAP Bitmap = hSize[i];
HBITMAP hBit = hBitmap[i];
HDC hDCBits = CreateCompatibleDC(hdc);
SelectObject(hDCBits, hBit);
StretchBlt(hdc, x, y, Bitmap.bmWidth, Bitmap.bmHeight,
hDCBits, 0, 0, Bitmap.bmWidth, Bitmap.bmHeight, SRCCOPY);
DeleteDC(hDCBits);
}
我 运行 一开始就是 "Load" 函数,我对它需要多长时间没有意见。我 运行 在我需要的程序中随时使用 newBit 函数。我特别使用 stretchBlt 命令,因为我需要调整大小的功能。如果能深入了解我做错了什么以及我可以改进什么,我们将不胜感激。
因为我怀疑它与你之前的问题 here 有关系,所以我 post 下面的回答。
如果您想在 window 中创建一些动画并加快速度,请考虑使用 GDI+ 而不是普通的 winapi。
使用 GDI+,您只需将绘图方法放入 WM_PAINT
消息中,并通过使您的控制矩形无效并更新 window.
来更新您的场景
例如:
InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow(hwnd);
WM_PAINT 消息处理可能如下所示:
case WM_PAINT:
{
/************************************************************************/
/* Initialize */
/************************************************************************/
hdc = BeginPaint(hwnd, &ps);
Graphics graphics(hdc);
Bitmap *pMemBitmap = new Bitmap(rect.right, rect.bottom);
Graphics* pMemGraphics = Graphics::FromImage(pMemBitmap);
SolidBrush back(Color(0, 0, 0));
pMemGraphics->FillRectangle(&back, 0, 0, rect.right, rect.bottom); // Fill your background with some color
pMemGraphics->SetSmoothingMode(SmoothingModeHighQuality); // Set your raster quality
graphics.SetSmoothingMode(SmoothingModeHighQuality);
// Rotate some primitive around your screen
static double x = M_PI + M_PI / 2;
x += 0.03f;
if(x > M_PI * 2)
{
x = 0;
}
double posX = cos(x);
double posY = sin(x);
Pen pen(Color(255, 255, 255, 0), 5);
pMemGraphics->DrawEllipse(&pen, (int)(posX * 50 - 15 + rect.right / 2), (int)(posY * 50 - 15 + rect.bottom / 2), 30, 30);
graphics.DrawImage(pMemBitmap, 0, 0); // Draw the entire bitmap to screen (double buffering)
/************************************************************************/
/* Cleanup */
/************************************************************************/
delete pMemGraphics;
delete pMemBitmap;
EndPaint(hwnd, &ps);
break;
}
为了避免闪烁,你应该告诉 winapi 不要像这样擦除背景:
case WM_ERASEBKGND:
{
return true; // Tell winapi, we already handled that.
}