Windows API BitBlt не работает для некоторых разрешенийC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Windows API BitBlt не работает для некоторых разрешений

Сообщение Anonymous »

Я написал простую программу на C++, которая захватывает экран с помощью BitBlt из Windows API и сохраняет его в файл, и некоторые разрешения, кажется, дают ошибки памяти, и я не могу найти шаблон/проблему в моем код.

Код: Выделить всё

#include 
#include 
#include 

BYTE* CaptureScreen(int x, int y, int width, int height);

bool CaptureScreenAndSaveToFile(int x, int y, int width, int height, const char* filename) {
BYTE* imageData = CaptureScreen(x, y, width, height);
if (imageData == nullptr) {
return false;
}

// Open file for writing
std::ofstream outFile(filename, std::ios::binary);
if (!outFile.is_open()) {
delete[] imageData; // Free allocated memory
return false;
}

// Write BMP file header
BITMAPFILEHEADER bmpFileHeader;
bmpFileHeader.bfType = 0x4D42; // 'BM'
bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + width * height * 3; // Total file size
bmpFileHeader.bfReserved1 = 0;
bmpFileHeader.bfReserved2 = 0;
bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); // Offset to pixel data

outFile.write(reinterpret_cast(&bmpFileHeader), sizeof(BITMAPFILEHEADER));

// Write BMP info header
BITMAPINFOHEADER bmpInfoHeader;
bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfoHeader.biWidth = width;
bmpInfoHeader.biHeight = -height;
bmpInfoHeader.biPlanes = 1;
bmpInfoHeader.biBitCount = 24; // 24 bits per pixel (RGB)
bmpInfoHeader.biCompression = BI_RGB;
bmpInfoHeader.biSizeImage = 0; // Size of the pixel data (can be set to 0 for BI_RGB compression)
bmpInfoHeader.biXPelsPerMeter = 0;
bmpInfoHeader.biYPelsPerMeter = 0;
bmpInfoHeader.biClrUsed = 0;
bmpInfoHeader.biClrImportant = 0;

outFile.write(reinterpret_cast(&bmpInfoHeader), sizeof(BITMAPINFOHEADER));

// Write image data
outFile.write(reinterpret_cast(imageData), width * height * 3);

// Close the file
outFile.close();

// Free allocated memory
delete[] imageData;

return true;
}

BYTE* CaptureScreen(int x, int y, int width, int height) {
BYTE* result = nullptr; // Initialize the result pointer to nullptr

HDC hdcTemp, hdc;
BYTE* bitPointer;

hdc = GetDC(HWND_DESKTOP);
if (hdc != NULL)
{
hdcTemp = CreateCompatibleDC(hdc);
if (hdcTemp != NULL)
{
BITMAPINFO bitmap;
bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
bitmap.bmiHeader.biWidth = width;
bitmap.bmiHeader.biHeight = -height; // Negative height to ensure the bitmap is top-down
bitmap.bmiHeader.biPlanes = 1;
bitmap.bmiHeader.biBitCount = 24;
bitmap.bmiHeader.biCompression = BI_RGB;
bitmap.bmiHeader.biSizeImage = 0;
bitmap.bmiHeader.biClrUsed = 0;
bitmap.bmiHeader.biClrImportant = 0;

HBITMAP hBitmap = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)&bitPointer, NULL, NULL);
if (hBitmap != NULL)
{
HBITMAP hPrevBitmap = (HBITMAP)SelectObject(hdcTemp, hBitmap); // Added explicit cast

BitBlt(hdcTemp, 0, 0, width, height, hdc, x, y, SRCCOPY);  // Use x, y, width, height
// Allocate memory on the heap and copy the buffer
result = new BYTE[width * height * 3];
if (result != nullptr) {
memcpy(result, bitPointer, width * height * 3);
}

// Select and delete objects
SelectObject(hdcTemp, hPrevBitmap);
DeleteObject(hBitmap);
}

DeleteDC(hdcTemp);
}

ReleaseDC(HWND_DESKTOP, hdc);
}

return result;
}

int main() {
CaptureScreenAndSaveToFile(125, 125, 35, 35, "Hello.png");
}
Я заметил, что при некоторых разрешениях сохраненный снимок экрана недоступен для просмотра, а когда я пытаюсь напрямую получить доступ к байт-буферу, выдается ошибка о недоступной памяти.
Вот разрешения, которые я пробовал, но не удались:
  • Все, что ниже (W: 36, H: 36)
  • И (W : 255, H: 255)
Я уверен, что есть еще много значений ширины и высоты, которые «не работают», но я не могу найти закономерность/ проблема здесь. Любая помощь будет оценена по достоинству.

Подробнее здесь: https://stackoverflow.com/questions/785 ... esolutions
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»