2012-05-09 33 views
8

Tôi đang cố gắng tạo tự động cho một ứng dụng cửa sổ. Nó hoạt động tốt, nhưng nó rất chậm! Tôi hiện đang sử dụng phương thức "getPixel" để tải lại một mảng mọi lúc được gọi.Nhận màu Pixel nhanh nhất?

Đây là mã hiện tại của tôi:

hdc = GetDC(HWND_DESKTOP); 
bx = GetSystemMetrics(SM_CXSCREEN); 
by = GetSystemMetrics(SM_CYSCREEN); 
start_bx = (bx/2) - (MAX_WIDTH/2); 
start_by = (by/2) - (MAX_HEIGHT/2); 
end_bx = (bx/2) + (MAX_WIDTH/2); 
end_by = (by/2) + (MAX_HEIGHT/2); 

for(y=start_by; y<end_by; y+=10) 
{ 
    for(x=start_bx; x<end_bx; x+=10) 
    { 
     pixel = GetPixel(*hdc, x, y); 
     if(pixel==RGB(255, 0, 0)) 
     { 
      SetCursorPos(x,y); 
      mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); 
      Sleep(50); 
      mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); 
      Sleep(25); 
     } 
    } 
} 

Vì vậy, về cơ bản, nó chỉ quét một loạt các điểm ảnh trên màn hình và bắt đầu một sự kiện chuột nếu nó phát hiện một nút màu đỏ.

Tôi biết có nhiều cách khác để có được màu pixel, chẳng hạn như bitblt. Nhưng tôi đã thực hiện một số nghiên cứu, và tôi không hiểu làm thế nào tôi phải làm, để quét một mảng màu. Tôi cần cái gì đó quét màn hình rất nhanh để nắm bắt các nút.

Bạn có thể giúp tôi không?

Cảm ơn.

+0

Khi mã của bạn được gọi? trong thời gian nhàn rỗi? khi người dùng di chuyển chuột? Có nhiều cách khác nhau để phát hiện một nút màu đỏ, sử dụng FindWindow() chẳng hạn. –

+0

Btw, mã của tôi nằm trong vòng lặp vô hạn. Nhưng tôi muốn sử dụng một màu bắt trong khi một bù đắp một. Vì vậy, khi tôi bắt đầu mã của tôi, nó chỉ đi vào vòng lặp và kiểm tra nút màu đỏ. – Manitoba

+2

Nếu mã này nằm trong vòng lặp vô hạn thì vấn đề không phải là 'GetPixel'. Thực tế là ứng dụng của bạn không cho phép các ứng dụng khác có bất kỳ thời gian CPU nào. – tenfour

Trả lời

11

Tôi tìm thấy một cách hoàn hảo mà rõ ràng là nhanh hơn so với GetPixel một:

HDC hdc, hdcTemp; 
RECT rect; 
BYTE* bitPointer; 
int x, y; 
int red, green, blue, alpha; 

while(true) 
{ 
    hdc = GetDC(HWND_DESKTOP); 
    GetWindowRect(hWND_Desktop, &rect); 
      int MAX_WIDTH = rect.right; 
     int MAX_HEIGHT = rect.bottom; 

    hdcTemp = CreateCompatibleDC(hdc); 
    BITMAPINFO bitmap; 
    bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader); 
    bitmap.bmiHeader.biWidth = MAX_WIDTH; 
    bitmap.bmiHeader.biHeight = MAX_HEIGHT; 
    bitmap.bmiHeader.biPlanes = 1; 
    bitmap.bmiHeader.biBitCount = 32; 
    bitmap.bmiHeader.biCompression = BI_RGB; 
    bitmap.bmiHeader.biSizeImage = MAX_WIDTH * 4 * MAX_HEIGHT; 
    bitmap.bmiHeader.biClrUsed = 0; 
    bitmap.bmiHeader.biClrImportant = 0; 
    HBITMAP hBitmap2 = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL); 
    SelectObject(hdcTemp, hBitmap2); 
    BitBlt(hdcTemp, 0, 0, MAX_WIDTH, MAX_HEIGHT, hdc, 0, 0, SRCCOPY); 

    for (int i=0; i<(MAX_WIDTH * 4 * MAX_HEIGHT); i+=4) 
    { 
     red = (int)bitPointer[i]; 
     green = (int)bitPointer[i+1]; 
     blue = (int)bitPointer[i+2]; 
     alpha = (int)bitPointer[i+3]; 

     x = i/(4 * MAX_HEIGHT); 
     y = i/(4 * MAX_WIDTH); 

     if (red == 255 && green == 0 && blue == 0) 
     { 
      SetCursorPos(x,y); 
      mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); 
      Sleep(50); 
      mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); 
      Sleep(25); 
     } 
    } 
} 

Tôi hy vọng điều này có thể giúp người khác.

+0

là việc này có kiểm tra từng điểm ảnh không? Tôi không hiểu bài tập x và y của bạn. – user1397417

+0

'X' và' Y' là vị trí của pixel đang được xem xét. Chúng vô ích, trừ khi bạn muốn thực hiện một hành động trên pixel này. Nếu màu của nó có màu đỏ, nó sẽ đặt con chuột vào điểm ảnh này và nhấp chuột trái. – Manitoba

+1

Công việc hay, nhưng có điều tôi không hiểu. Tại sao phải tính đến byte được gán cho thành phần Alpha của pixel? Bởi vì vì nó là một ảnh chụp màn hình, giá trị của alpha sẽ luôn là 255, phải không? Vì vậy, nó sẽ không được tốt hơn làm cho tham số biBitCount trị giá 24? – Delgan

1

Câu trả lời đơn giản là nếu đây là phương pháp bạn nhấn mạnh vào việc sử dụng thì không có nhiều thứ để tối ưu hóa. Như những người khác đã chỉ ra trong ý kiến, bạn có lẽ nên sử dụng một phương pháp khác nhau để xác định vị trí khu vực để click. Hãy xem xét việc sử dụng FindWindow, ví dụ.

Nếu bạn không muốn thay đổi phương pháp của mình, thì ít nhất hãy ngủ một chút sau mỗi lần quét toàn màn hình.

+0

Xin chào, Bạn có thể cho tôi biết thêm về Findwindow không? Tôi đang sử dụng nó như thế: 'mhwnd = FindWindow (NULL," Tên cửa sổ ứng dụng "); hdc = GetDC (mhwnd); 'Tiếp theo là gì? – Manitoba

+1

Nút bạn muốn nhấp có thể có tay cầm cửa sổ. Hãy thử sử dụng một chương trình kiểm tra cửa sổ như Spy ++ để tìm cửa sổ xử lý của thứ bạn muốn nhấn, và bạn có thể xác định vị trí mục cụ thể đó với một số mã thông minh. – korona

Các vấn đề liên quan