如何将图像写入Rust中的Windows剪贴板

问题描述 投票:0回答:1

我想使用Rust将本地图像放入剪贴板。我使用了clipboard-winimage板条箱。我的代码如下,但它不起作用。

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后没有显示任何内容。我该如何更正此代码?

windows rust clipboard
1个回答
1
投票

你有很多问题。

Format

PNG format image不是bitmap format image,即使它是bitmap

一个thread on MSDN说:

PNG没有标准化的剪贴板格式。

您可以注册自己的格式,但只有您可以识别剪贴板。如果使用标准位图或文件格式,则更多应用程序可以接受您的数据。

Error handling

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写入文件会生成Paint可以读取的BMP,但剪贴板数据仍然无效。在尝试调试差异时,我遇到了low-level crashes in the library,这表明尽管有2.x版本号,但它可能还没有为一般用途做好准备。

我认为根本问题是

Windows期望

位图的句柄(HBITMAP)。

BITMAP是一个结构,包含有关位图的一组信息,例如宽度和高度。这可能与位图的磁盘格式不同。

似乎有理由将位图数据拟合成这种预期的格式对解决问题有很大帮助。

另一种途径是研究使用CF_DIB而不是CF_BITMAP。与上面链接的论坛帖子相反,CF_DIB期望指向具有BITMAPINFO字段的BITMAPINFOHEADER。这引用了BI_PNG压缩,这可能允许您在不执行转换的情况下提交PNG。

也可以看看:

© www.soinside.com 2019 - 2024. All rights reserved.