我想使用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后没有显示任何内容。我该如何更正此代码?
你有很多问题。
PNG format image不是bitmap format image,即使它是bitmap。
一个thread on 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
写入文件会生成Paint可以读取的BMP,但剪贴板数据仍然无效。在尝试调试差异时,我遇到了low-level crashes in the library,这表明尽管有2.x版本号,但它可能还没有为一般用途做好准备。
我认为根本问题是
Windows期望
位图的句柄(
HBITMAP
)。
BITMAP
是一个结构,包含有关位图的一组信息,例如宽度和高度。这可能与位图的磁盘格式不同。
似乎有理由将位图数据拟合成这种预期的格式对解决问题有很大帮助。
另一种途径是研究使用CF_DIB
而不是CF_BITMAP
。与上面链接的论坛帖子相反,CF_DIB
期望指向具有BITMAPINFO
字段的BITMAPINFOHEADER
。这引用了BI_PNG
压缩,这可能允许您在不执行转换的情况下提交PNG。
也可以看看: