Привет, я использовал метод getpixel, bitblt или как его вызывали (создавая заголовок растрового изображения), а затем перебрал все значения. Это очень медленно. Например, если бы я должен был обнаружить что-то красное или определенный цвет, это заняло бы очень много времени. Должно быть быстрее, не так ли? Я попытался использовать рабочий стол в качестве HWND, а затем окно, в котором мне нужно было найти цвета, но рабочий стол был как-то быстрее … думаю, потому что он должен был искать окно, я думаю. Я получаю ВЫСОКОЕ использование процессора, используя оба метода.
void Get_Color(int x,int y,int w,int h,int &red,int &green,int &blue,int action)
{
HDC hdc, hdcTemp;
RECT rect;
BYTE*bitPointer;
HWND Desktop = GetDesktopWindow();
hdc = GetDC(Desktop);
GetWindowRect(Desktop, &rect);
hdcTemp = CreateCompatibleDC(hdc);
BITMAPINFO bitmap;
bitmap.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmap.bmiHeader.biWidth = w;
bitmap.bmiHeader.biHeight = h;
bitmap.bmiHeader.biPlanes = 1;
bitmap.bmiHeader.biBitCount = 32;
bitmap.bmiHeader.biCompression = BI_RGB;
bitmap.bmiHeader.biSizeImage = 0;
bitmap.bmiHeader.biClrUsed = 0;
bitmap.bmiHeader.biClrImportant = 0;
HBITMAP hBitmap2 = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
HGDIOBJ save = SelectObject(hdcTemp, hBitmap2);
BitBlt(hdcTemp, 0, 0, w, h, hdc, x, y, SRCCOPY);
if(action==1)
{
for(int j=0;j<=w*h*4;j+=4)
{
red = bitPointer[j+2];
green = bitPointer[j+1];
blue = bitPointer[j];
if(red<30 && green>190 && blue>190)
{
break;
}
}
}
else
{
for(int j=0;j<=w*h*4;j+=4)
{
red = bitPointer[j+2];
green = bitPointer[j+1];
blue = bitPointer[j];
break;
}
}
///RELEASE
DeleteObject( SelectObject(hdcTemp, save) );
DeleteDC(hdcTemp);
DeleteDC(hdc);
ReleaseDC(NULL,hdc);
ReleaseDC(NULL,hdcTemp);
}
Вы можете попытаться прервать ваш поиск. Сначала ищите в красном канале и, когда это удастся, найдите значения синего и зеленого:
for (int j=0; j<=w*h*4; j+=4){
red = bitPointer[j+2];
if (red<30) {
green = bitPointer[j+1];
blue = bitPointer[j];
if (green>190 && blue>190) {
do_something;
}
}
}
Вы также можете попытаться ускорить с помощью арифметики с указателями (но хороший компилятор легко оптимизирует первый):
for (BYTE *pRed=bitPointer+2; pRed<=bitPointer+w*h*4; pRed+=4){
if (pRed<30) {
green = pRed[-1];
blue = pRed[-2];
if (green>190 && blue>190) {
do_something;
}
}
}
Если этого недостаточно, вы можете подумать об использовании потоков, чтобы разбить поиск на отдельные параллели меньших поисков.
Я предлагаю вам создать таблицу значений RGB из растрового изображения. Это нужно будет выполнить только один раз.
struct RGB
{
unsigned int red;
unsigned int green;
unsigned int blue;
};
RGB rgb_pixels[MAX_ROWS][MAX_COLUMNS];
// ...
for (unsigned int row = 0; row < MAX_ROWS; ++row)
{
for (unsigned int column = 0; column < MAX_COLUMNS; ++column)
{
unsigned red = get_red_value(row, column);
unsigned green = get_green_value(row, column);
unsigned blue = get_blue_value(row, column);
RGB pixel;
pixel.red = red;
pixel.green = green;
pixel.blue = blue;
rgb_pixels[row][column] = pixel;
}
}
Всякий раз, когда вашей программе требуется информация RGB из растрового изображения, индексируйте массив (rgb_pixels
).
Доступ к массиву пикселей RGB будет намного быстрее, чем поиск растрового изображения и преобразование для каждого интересующего вас пикселя.
По сути, каждый раз, когда вы вызываете ваш метод, он создает совершенно новое растровое изображение и снова копирует его. Вы могли бы максимально ускорить вашу программу, сохраняя массив цветов между вызовами Get_Color (). Вы можете поместить его в класс или глобальную переменную. У Томаса Мэтьюса есть хорошая идея для этого. После исправления у Жан-Батиста Юнеса есть несколько полезных советов.