简体   繁体   English

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

[英]How to write an image to the Windows clipboard in Rust

I want to put a local image into the clipboard using Rust. 我想使用Rust将本地图像放入剪贴板。 I used the clipboard-win and image crates. 我使用了剪贴板式图像包装箱。 My code is as follows, but it doesn't work. 我的代码如下,但是它不起作用。

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());
}

After execution, there seems to be content in the pasteboard, but there is nothing displayed after Ctrl + V . 执行后,粘贴板中似乎有内容,但是在Ctrl + V之后没有任何显示。 How can I correct this code? 如何更正此代码?

You have multiple problems. 您有多个问题。

Format 格式

A PNG format image is not a bitmap format image , even though it is a bitmap . 一个PNG格式的图片是不是一个位图格式的图像 ,即使它是一个 位图

A thread on MSDN states: MSDN上的一个线程指出:

There isn't a standardized clipboard format for PNG. 没有用于PNG的标准化剪贴板格式。

You can register your own format, but then only you can recognize the clipboard. 您可以注册自己的格式,但是只有您可以识别剪贴板。 If you use the standard bitmap or file format then more applications can accept your data. 如果您使用标准位图或文件格式,则更多应用程序可以接受您的数据。

Error handling 错误处理

Clipboard::set can fail and it returns a Result . Clipboard::set可能失败,并返回Result You need to handle this case . 您需要处理这种情况 The compiler even told you about this: 编译器甚至告诉您以下内容:

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

Don't ignore warnings, especially when trying to debug a problem. 不要忽略警告, 尤其是在尝试调试问题时。


Unfortunately, this is as far as I got: 不幸的是,据我所知:

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");
}

Writing data to a file produces a BMP that Paint can read, but the clipboard data is still invalid. data写入文件会生成一个Paint可以读取的BMP,但是剪贴板数据仍然无效。 While attempting to debug the differences, I ran into low-level crashes in the library , which suggests it may not be ready for general use, despite the 2.x version number. 在尝试调试差异时,我在库中遇到了低级崩溃 ,这表明尽管有2.x版本号,它可能仍未准备好用于一般用途。

I believe that the root problem is that 我认为根本问题是

Windows expects Windows期望

A handle to a bitmap ( HBITMAP ). 位图的句柄( HBITMAP )。

A BITMAP is a struct with a set of information about the bitmap, such as width and height. BITMAP是一种结构,其中包含有关位图的一组信息,例如宽度和高度。 This is likely different from the on-disk format of the bitmap. 这可能与位图的磁盘格式不同。

It seems plausible that fitting the bitmap data into this expected format would go a long way to solving the problem. 将位图数据拟合为这种预期格式似乎对解决问题大有帮助。

Another avenue is to look into using CF_DIB instead of CF_BITMAP . 另一个途径是研究使用CF_DIB而不是CF_BITMAP Contrary to the linked forum post above, CF_DIB expects a pointer to a BITMAPINFO which has a BITMAPINFOHEADER field. 与上面链接的论坛帖子相反, CF_DIB需要指向具有BITMAPINFOHEADER字段的BITMAPINFO的指针。 This makes a reference to a BI_PNG compression, which might allow you to submit a PNG without performing transformations. 这引用了BI_PNG压缩,这可能使您无需执行转换即可提交PNG。

See also: 也可以看看:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM