Я работаю над проектом, который пытаюсь разработать для класса. Я хочу попробовать подражать поведению Филипса «Abilight» или обычного доморощенного «BobLight». В моем случае он получает средний цвет экрана посредством скриншота, усредняя пиксельные данные RGB, пиксель за пикселем. Я решил попробовать это сделать с помощью API Windows GDI, и пока я получаю довольно неплохие результаты, я научился не использовать GetPixel () для чтения данных пикселей, поскольку он невероятно медленный, и моя скорость вполне приемлема, поэтому далеко.
Моя проблема в том, что когда я пытаюсь реализовать его в цикле, который может работать столько времени, сколько нужно, он в конечном итоге зависает, давая мне сообщение об ошибке: std :: bad_alloc в ячейке памяти 0x0027F9C4.
в этой строке кода:
BYTE *lpbitmap = new BYTE[dwBmpSize];
Я приложил весь мой код ниже
У кого-нибудь есть идея, что может быть причиной этой ошибки? У меня не должно быть никаких воспоминаний, и я действительно в растерянности ..
Заранее благодарю за любую помощь!
#define _WIN32_WINNT 0x0501 //xp
#include <windows.h>
#include <iostream>
#include <vector>
#include <time.h>
#define NUM_FRAMES 180
using namespace std;int main()
{
int time_start, time_finish;
float time_total;
time_start = clock();
for(int z = 0; z < NUM_FRAMES; z++)
{
HDC hScreenDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
// and a device context to put it in
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
int x = GetDeviceCaps(hScreenDC, HORZRES);
int y = GetDeviceCaps(hScreenDC, VERTRES);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, x, y);
// get a new bitmap
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);RECT desktop;
// Get a handle to the desktop window
const HWND hDesktop = GetDesktopWindow();
// Get the size of screen to the variable desktop
GetWindowRect(hDesktop, &desktop);
// The top left corner will have coordinates (0,0)
// and the bottom right corner will have coordinates
// (horizontal, vertical)
int horizontal = desktop.right;
int vertical = desktop.bottom;BitBlt(hMemoryDC, 0, 0, horizontal, vertical, hScreenDC, 0, 0, SRCCOPY);
hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = horizontal;
bi.biHeight = vertical;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
DWORD dwBmpSize = ((horizontal * bi.biBitCount + 31) / 32) * 4 * vertical;
// Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that
// call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc
// have greater overhead than HeapAlloc.
HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize);
BYTE *lpbitmap = new BYTE[dwBmpSize];//BITMAP bm;
GetDIBits(hMemoryDC,hBitmap,0,(UINT)vertical,lpbitmap, (BITMAPINFO *)&bi, DIB_RGB_COLORS);
GetObject (hBitmap, sizeof(lpbitmap), &lpbitmap);unsigned long red = 0, green = 0, blue = 0;
for (int i = 0; i < horizontal; i++)
{
for (int j = 0; j < vertical; j++)
{
blue += lpbitmap[0];
green += lpbitmap[1];
red += lpbitmap[2];
lpbitmap += 4;
}
}
red = red/(horizontal*vertical);
green = green/(horizontal*vertical);
blue = blue/(horizontal*vertical);
//cout << "Red: " << red << " Green: " << green << " Blue: " << blue << endl;
}
time_finish = clock();
time_total = time_finish - time_start;
cout << endl << NUM_FRAMES/((time_total)/10000) << endl;
//release
//DeleteDC(hdc);
//DeleteObject(hbmp);
//ReleaseDC(NULL, hdcScreen);
std::system("pause");
return 0;
}
Ваш код выпуска, кажется, закомментирован, то есть вы по крайней мере, утечка hBitmap
каждый кадр, который будет складываться быстро (около 470 МБ / с, если быть точным). На самом деле, похоже, что вы протекаете lpbitmap
Кроме того, ваши 180 кадров будут записывать около 2,8 ГБ на дисплее 1080p.
Других решений пока нет …