2015-08-15 3 views
-1

Я ищу ускорение программы отображения растровых изображений. Это не ужасно медленно, я просто думаю, что это может быть быстрее. Я запускаю его в среде Win32. Вот код:C++ 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); 
} 

Я запускаю функцию «Загрузить» в начале, и мне хорошо, сколько времени потребуется. Я запускаю функцию newBit всякий раз, когда в программе, которая мне нужна. Я специально использую команду stretchBlt, потому что мне нужна возможность изменения размера. Любое понимание того, что я делаю неправильно, и то, что я могу улучшить, будет оценено по достоинству.

+0

Вам нужно сохранить результат 'SelectObject (hDCBits, hBit);' на HBITMAP, а затем вернуть его обратно в hDCBits до удаления HDC. Несоблюдение этого требования приведет к утечке ресурсов. Ручки GDI - это ограниченный ресурс. Кроме того, поскольку вы кэшируете загруженные изображения, вы должны добавить еще одну переменную, чтобы вы только однажды создали и уничтожали HDC. Вы можете получить исходное растровое изображение, которое выбрано в нем, с вызовом 'GetCurrentObject (hDCBits, OBJ_BITMAP);', чтобы (a) вам нужно было только сохранить его копию и (b) вы можете восстановить это растровое изображение до окончательного уничтожения HDC. – enhzflep

ответ

-2

Поскольку я подозреваю, что он должен что-то сделать с вашим предыдущим вопросом here, я отправляю следующий ответ.

Если вы хотите создать анимацию в своем окне и хотите ускорить работу, подумайте об использовании GDI + вместо простого winapi. С помощью GDI + вы просто разместите свои методы рисования в сообщении WM_PAINT и обновите свою сцену с помощью недействительности вашего элемента управления и обновления окна.
Например что-то вроде этого:

обработка сообщений
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. 
} 
+1

Не мог ли пояснитель объяснить мне, почему он это сделал? – ProXicT

+3

Это, вероятно, не произойдет. Возможная причина может быть: GDI + не принесет вам больше производительности. Он реализован в программном обеспечении и обычно будет медленнее, чем GDI. Улучшения производительности более вероятны с помощью [Компонент обработки изображений Windows] (https://msdn.microsoft.com/en-us/library/windows/desktop/ee719902.aspx) вместе с [Direct2D] (https: // msdn. microsoft.com/en-us/library/windows/desktop/dd370990.aspx). – IInspectable

+0

Я все еще думаю, что использование GDI + будет работать лучше обычного winapi. Конечно, он может использовать некоторые ускоренные библиотеки с графическим процессором, такие как OpenGL или Direct2D, но из того, что я читал, он хочет сделать, GDI + - enaugh. – ProXicT