Я написал простую программу на 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)
Я уверен, что есть еще много значений ширины и высоты, которые «не работают», но я не могу найти закономерность/ проблема здесь. Любая помощь будет оценена по достоинству.
Я написал простую программу на C++, которая захватывает экран с помощью BitBlt из Windows API и сохраняет его в файл, и некоторые разрешения, кажется, дают ошибки памяти, и я не могу найти шаблон/проблему в моем код. [code]#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; }
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"); } [/code] Я заметил, что при некоторых разрешениях сохраненный снимок экрана недоступен для просмотра, а когда я пытаюсь напрямую получить доступ к байт-буферу, выдается ошибка о недоступной памяти. Вот разрешения, которые я пробовал, но не удались: [list] [*]Все, что ниже (W: 36, H: 36) [*]И (W : 255, H: 255) [/list] Я уверен, что есть еще много значений ширины и высоты, которые «не работают», но я не могу найти закономерность/ проблема здесь. Любая помощь будет оценена по достоинству.