gpt4 book ai didi

c++ - 使用 C++ 和 GDI 分析屏幕截图以获得屏幕的平均颜色

转载 作者:太空宇宙 更新时间:2023-11-04 13:58:23 29 4
gpt4 key购买 nike

我正在做一个项目,我想为一个类(class)设计。我想尝试模仿 Phillips 的 Abilight 或常见的自制程序“BobLight”的行为。它通过屏幕截图获得屏幕的平均颜色,在我的例子中是通过逐像素平均 RGB 像素数据。我决定尝试使用 Windows GDI api 来做到这一点,到目前为止我得到了一些非常好的结果,我学会了不使用 GetPixel() 来读取像素数据,因为它非常慢,而且我的速度是完全可以接受的所以远。

我的问题是,当我尝试在一个可以运行任意长的循环中实现它时,它最终挂起并给我一个错误消息:std::bad_alloc at memory location 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,这将很快加起来(具体来说大约是 470MB/s)。实际上,您似乎也在泄漏 lpbitmap,因此您的 180 帧在 1080p 显示器上将消耗大约 2.8 GB。

关于c++ - 使用 C++ 和 GDI 分析屏幕截图以获得屏幕的平均颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20364429/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com