Как записать изображение в буфер обмена Windows в Rust - PullRequest
0 голосов
/ 06 апреля 2019

Я хочу поместить локальное изображение в буфер обмена с помощью Rust. Я использовал ящики clipboard-win и image . Мой код выглядит следующим образом, но он не работает.

extern crate clipboard_win;
extern crate image;

use clipboard_win::{formats, Clipboard};
use image::GenericImageView;

fn main() {
    let img = image::open("C:\\Users\\Crash\\Desktop\\20190405221505.png").unwrap();
    Clipboard::new()
        .unwrap()
        .set(formats::CF_BITMAP, &img.raw_pixels());
}

После выполнения кажется, что в монтажном столе есть содержимое, но после Ctrl + V ничего не отображается. Как я могу исправить этот код?

1 Ответ

1 голос
/ 07 апреля 2019

У вас несколько проблем.

Формат

A Изображение в формате PNG не является растровым изображением , даже если оно a растровое изображение .

A поток в MSDN сообщает:

Нет стандартного формата буфера обмена для PNG.

Вы можете зарегистрировать свой собственный формат, но тогда только вы можете распознать буфер обмена.Если вы используете стандартное растровое изображение или формат файла, то больше приложений могут принимать ваши данные.

Обработка ошибок

Clipboard::set может завершиться с ошибкой и возвращает Result. Вам нужно разобраться с этим делом .Компилятор даже сказал вам об этом:

warning: unused `std::result::Result` that must be used
  --> src\main.rs:11:5
   |
11 | /     Clipboard::new()
12 | |         .unwrap()
13 | |         .set(formats::CF_BITMAP, &data);
   | |________________________________________^
   |
   = note: #[warn(unused_must_use)] on by default
   = note: this `Result` may be an `Err` variant, which should be handled

Не игнорируйте предупреждения, особенно при попытке отладки проблемы.


К сожалению, это то, что я получил:

use clipboard_win::{formats, Clipboard}; // 2.1.2
use image::ImageOutputFormat; // 0.21.0

fn main() {
    let img = image::open("unicorn.png").unwrap();

    let mut data = Vec::new();
    img.write_to(&mut data, ImageOutputFormat::BMP)
        .expect("Unable to transform");

    Clipboard::new()
        .unwrap()
        .set(formats::CF_BITMAP, &data)
        .expect("Unable to set clipboard");
}

Запись data в файл создает BMP, который Paint может прочитать, но данные буфера обмена по-прежнему недействительны.Пытаясь отладить различия, я столкнулся с низкоуровневыми сбоями в библиотеке , что говорит о том, что она может быть не готова для общего использования, несмотря на номер версии 2.x.

Iполагать, что основная проблема заключается в том, что

Windows ожидает

Дескриптор растрового изображения (HBITMAP).

A BITMAP - это структура с набором информации о растровом изображении, такой как ширина и высота.Вероятно, это отличается от формата растрового изображения на диске.

Представляется вероятным, что подгонка растровых данных к этому ожидаемому формату будет иметь большое значение для решения проблемы.

Другой путьэто использовать CF_DIB вместо CF_BITMAP.В отличие от связанного поста на форуме выше, CF_DIB ожидает указатель на BITMAPINFO, который имеет поле BITMAPINFOHEADER.Это ссылка на сжатие BI_PNG, которое может позволить вам отправлять PNG без выполнения преобразований.

См. Также:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...