使用DIB部分可直接快速访问像素
例如,此测试将记事本中的所有白色像素替换为绿色像素
HDC hDCScreen = GetDC(NULL); HWND hWndDest = FindWindow(L"Notepad", NULL); if (hWndDest) { if (IsIconic(hWndDest)) { ShowWindow(hWndDest, SW_RESTORE); Sleep(100); } RECT rect; GetWindowRect(hWndDest, &rect); int nWidth = rect.right - rect.left; int nHeight = rect.bottom - rect.top; HDC hDC = GetDC(hWndDest); HDC hCaptureDC = CreateCompatibleDC(hDCScreen); HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDCScreen, nWidth, nHeight); HGDIOBJ hOldBitmap = SelectObject(hCaptureDC, hCaptureBitmap); PrintWindow(hWndDest, hCaptureDC, PW_RENDERFULLCONTENT); HDC hDCMem = CreateCompatibleDC(hDC); HBITMAP hBitmapOld; BITMAPINFO bi = { 0 }; bi.bmiHeader.biSize = sizeof(bi.bmiHeader); bi.bmiHeader.biWidth = nWidth; bi.bmiHeader.biHeight = nHeight; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 32; bi.bmiHeader.biCompression = BI_RGB; BYTE *pbBitmap; HBITMAP hBitmap = CreateDIBSection(hDCMem, &bi, DIB_RGB_COLORS, (void**)&pbBitmap, NULL, 0); if (hBitmap) { hBitmapOld = (HBITMAP)SelectObject(hDCMem, hBitmap); BitBlt(hDCMem, 0, 0, nWidth, nHeight, hCaptureDC, 0, 0, SRCCOPY); RGBQUAD *pRGB; LONG nPixels; for (pRGB = (RGBQUAD *)pbBitmap, nPixels = nWidth * nHeight; nPixels > 0; ++pRGB, --nPixels) { ULONG nRed = pRGB->rgbRed; ULONG nGreen = pRGB->rgbGreen; ULONG nBlue = pRGB->rgbBlue; if (nRed == 255 && nGreen == 255 && nBlue == 255) { pRGB->rgbRed = 0; pRGB->rgbGreen = 255; pRGB->rgbBlue = 0; } } // Test copy to screen BitBlt(hDCScreen, 0, 0, nWidth, nHeight, hDCMem, 0, 0, SRCCOPY); SelectObject(hDCMem, hBitmapOld); DeleteObject(hBitmap); } DeleteDC(hDCMem); hOldBitmap = SelectObject(hCaptureDC, hOldBitmap); DeleteDC(hCaptureDC); DeleteObject(hCaptureBitmap); ReleaseDC(hWndDest, hDC); } ReleaseDC(NULL, hDCScreen);
参考: https://stackoverflow.com/questions/57078206/how-to-iterate-through-bitmap-pixels/57081780#57081780