@FlensT

Как получить скриншот при помощи winapi, используя Rust?

На данный момент есть такой код (не самый лучший, главная задача заставить его работать):
Code

use winapi::*;
use std::ptr;
use ::core::mem::size_of;

fn get_sct(){
    unsafe{
        let mut HDC_screen = um::winuser::GetDC(ptr::null_mut());
        let mut HDC_compatible_DC = um::wingdi::CreateCompatibleDC(HDC_screen);

        let bmi = um::wingdi::BITMAPINFO {
            bmiHeader: um::wingdi::BITMAPINFOHEADER {
                biSize: size_of::<um::wingdi::BITMAPINFOHEADER>() as shared::minwindef::DWORD,
                biWidth: 1920,
                biHeight: 1080,
                biPlanes: 1,
                biBitCount: 32,
                biCompression: um::wingdi::BI_RGB,
                biSizeImage: 0,
                biXPelsPerMeter: 0,
                biYPelsPerMeter: 0,
                biClrUsed: 0,
                biClrImportant: 0,
            },
            bmiColors: [um::wingdi::RGBQUAD {
                rgbBlue: 0,
                rgbGreen: 0,
                rgbRed: 0,
                rgbReserved: 0
            }],
        };
        let mut my_dib_data: *mut ctypes::c_void = ptr::null_mut();
        let hbitmap: shared::windef::HBITMAP = um::wingdi::CreateDIBSection(HDC_screen, 
                                                                            &bmi, 
                                                                            um::wingdi::DIB_RGB_COLORS, 
                                                                            &mut my_dib_data,
                                                                            ptr::null_mut(),
                                                                            0);

        um::wingdi::SelectObject(HDC_compatible_DC, hbitmap as shared::windef::HGDIOBJ);
        let my_bit_blt: shared::minwindef::BOOL = um::wingdi::BitBlt(HDC_compatible_DC, 
                                                                    0, 
                                                                    0, 
                                                                    1920, 
                                                                    1080, 
                                                                    HDC_screen, 
                                                                    0, 
                                                                    0,
                                                                    um::wingdi::SRCCOPY);
        println!("{}", my_bit_blt);
    }
}


BitBlt выводит "True", т.е. пиксели копируются, но я не понимаю что мне нужно делать дальше.
Подскажите как дальше мне нужно действовать чтобы сохранить и/или просто получить нужную информацию для дальнейшего перевода "этого" в объект "Mat" библиотеки opencv.
Главная задача создать из этого объект opencv "Mat", дальнейшей работы с изображением полученным таким методом.
  • Вопрос задан
  • 261 просмотр
Пригласить эксперта
Ответы на вопрос 1
Torin_Asakura
@Torin_Asakura
Lead Architect
Мыслишь в верном направлении, однако, есть нюансы:

1. Когда ты используешь `BitBlt` для копирования пикселей в `HDC_compatible_DC`, изображение сохраняется в `HBITMAP`. Ты уже создал `HBITMAP` через `CreateDIBSection`, и указатель `my_dib_data` теперь должен указывать на данные пикселей.

2. Для создания объекта `Mat` в OpenCV, тебе нужно скопировать данные из `my_dib_data` в `Mat`. OpenCV имеет конструктор `Mat`, который принимает размеры изображения, тип данных и указатель на данные.

Псевдокод

use opencv::prelude::*;
use opencv::core::{Mat, CV_8UC4};

unsafe {
    let height = 1080;
    let width = 1920;
    let mat = Mat::new_rows_cols_with_data(
        height,
        width,
        CV_8UC4,
        my_dib_data,
        Mat_AUTO_STEP
    ).unwrap();

    um::wingdi::DeleteObject(hbitmap as shared::windef::HGDIOBJ);
    um::wingdi::DeleteDC(HDC_compatible_DC);
    um::winuser::ReleaseDC(ptr::null_mut(), HDC_screen);
}


Что важно понимать:
- Ты должен корректно освободить все ресурсы (`HBITMAP`, `HDC`, и т.д.) после их использования.
- Убедись, что `my_dib_data` действительно содержит данные изображения. Null safety для `CreateDIBSection`
- В зависимости от конкретной настройки и требований, возможно, придется выполнить преобразование формата пикселей, так как формат в `BITMAPINFO` и `Mat` могут отличаться
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы