CaptureMode.screen now working on Windows 10
All the other CaptureMode works, but CaptureMode.screen doesn't.
The CapturedData? capturedData will return null, and if the path is specified no file is created.
No error is showing.
i have the same issue and i need a solution
+1
+1
i have the same problem
I might be able to suggest a PR
This is an issue with the plugin, and while I was working on it, I created some custom script that worked for me. It captures the image in bmp format, and then in the dart code, I convert it to png file to the given path.
screenshot.cc
#include <windows.h>
#include <fstream>
#include <iostream>
extern "C" __declspec(dllexport) void CaptureScreenshot() {
std::cout << "Starting screenshot capture..." << std::endl;
int width = GetSystemMetrics(SM_CXSCREEN);
int height = GetSystemMetrics(SM_CYSCREEN);
std::cout << "Screen dimensions: " << width << "x" << height << std::endl;
HDC hdcDesktop = GetDC(NULL); // Get desktop DC
HDC hdcCompatible = CreateCompatibleDC(hdcDesktop);
HBITMAP hBitmap = CreateCompatibleBitmap(hdcDesktop, width, height);
SelectObject(hdcCompatible, hBitmap);
if (!BitBlt(hdcCompatible, 0, 0, width, height, hdcDesktop, 0, 0, SRCCOPY)) {
std::cerr << "Failed to perform BitBlt operation." << std::endl;
DeleteDC(hdcCompatible);
ReleaseDC(NULL, hdcDesktop);
return;
}
// Prepare bitmap headers
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
BITMAP bmp;
GetObject(hBitmap, sizeof(BITMAP), &bmp);
int rowSize = ((bmp.bmWidth * 24 + 31) / 32) * 4; // Rows must be padded to 4 bytes
int imageSize = rowSize * bmp.bmHeight;
fileHeader.bfType = 0x4D42; // 'BM' for Bitmap
fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + imageSize;
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
infoHeader.biSize = sizeof(BITMAPINFOHEADER);
infoHeader.biWidth = bmp.bmWidth;
infoHeader.biHeight = -bmp.bmHeight; // Negative for top-down DIB
infoHeader.biPlanes = 1;
infoHeader.biBitCount = 24; // Assuming 24-bit color depth
infoHeader.biCompression = BI_RGB;
infoHeader.biSizeImage = imageSize;
infoHeader.biXPelsPerMeter = 0;
infoHeader.biYPelsPerMeter = 0;
infoHeader.biClrUsed = 0;
infoHeader.biClrImportant = 0;
// Create file and write headers and pixel data
std::ofstream outFile("screenshot.bmp", std::ios::binary);
if (!outFile) {
std::cerr << "Failed to create file." << std::endl;
DeleteDC(hdcCompatible);
DeleteObject(hBitmap);
ReleaseDC(NULL, hdcDesktop);
return;
}
// Write BMP headers
outFile.write(reinterpret_cast<char*>(&fileHeader), sizeof(fileHeader));
outFile.write(reinterpret_cast<char*>(&infoHeader), sizeof(infoHeader));
// Write pixel data
BYTE* buffer = new BYTE[imageSize];
GetDIBits(hdcCompatible, hBitmap, 0, bmp.bmHeight, buffer, reinterpret_cast<BITMAPINFO*>(&infoHeader), DIB_RGB_COLORS);
outFile.write(reinterpret_cast<char*>(buffer), imageSize);
// Cleanup
delete[] buffer;
outFile.close();
DeleteDC(hdcCompatible);
DeleteObject(hBitmap);
ReleaseDC(NULL, hdcDesktop);
std::cout << "Screenshot captured and saved as 'screenshot.bmp'." << std::endl;
}
screen_capture_service.dart
import 'dart:ffi';
import 'dart:io';
import 'dart:typed_data';
import 'package:image/image.dart' as img;
class ScreenCaptureService {
Future<void> captureScreenshot(String path) async {
try {
print('capture screenshot: native.dll');
final DynamicLibrary nativeLib = DynamicLibrary.open('native.dll');
final captureScreenshot =
nativeLib.lookupFunction<Void Function(), void Function()>(
'CaptureScreenshot',
);
print('capturing');
captureScreenshot();
await _convertBmpToPng('screenshot.bmp', path);
print('Screenshot captured successfully');
} catch (e) {
print("Failed to capture screenshot: $e");
}
}
Future<void> _convertBmpToPng(String bmpPath, String pngPath) async {
// Read the BMP file
final File bmpFile = File(bmpPath);
final Uint8List bmpBytes = await bmpFile.readAsBytes();
img.Image? image = img.decodeImage(bmpBytes);
if (image != null) {
// Convert to PNG
List<int> pngBytes = img.encodePng(image);
// Save the PNG to a specific file location
final File pngFile = File(pngPath);
await pngFile.writeAsBytes(pngBytes);
print('Screenshot converted to PNG and saved successfully');
} else {
print('Failed to decode BMP image');
}
}
}
native.dll is compiled version of screenshot.cc.
capture.dart
if (Platform.isWindows) {
final ScreenCaptureService _screenCaptureService = ScreenCaptureService();
await _screenCaptureService.captureScreenshot("$path/$key.png");
print('saved file to $path/$key.png');
} else {
await ScreenCapturer.instance.capture(
mode: CaptureMode.screen,
imagePath: "$path/$key.png",
silent: true,
copyToClipboard: false);
}