1Password / arboard

A clipboard for Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Preserving image transparency on Windows

Klavionik opened this issue · comments

Hello!

I'm authoring copykitten, a Python library that provides clipboard operations utilizing arboard under the hood. I have an issue report from a user, who has a problem pasting transparent images into PowerPoint on Windows: Klavionik/copykitten#5. I was able to confirm this issue and now looking for a solution.

There's one way, which is to make arboard put images into the clipboard not only in bitmap and DIB formats but also as a PNG file. This is a trick used by Google Chrome, for example. I believe this would be useful for many Windows applications, not only PowerPoint.

I have a working draft of code that does that and as far as I can see it works fine. If you are interested in this I could work on a pull request implementing this feature.

Hey @Klavionik,

At first glance I think this would be fine. Would you be able to detail about what this would entail? After looking around for a bit I see:

  • BITMAPV5HEADER supports setting bV5Compression to BI_PNG. With that set, a number of other fields are basically just passing in PNG metadata like height, width, etc.
  • This could switch based on if the user has copied a format with transparency (like PNG) vs raw RBG(A) bytes. This could be trivially detected by looking at magic bytes.

Hey!

I suppose this could be done by having a method similar to add_cf_dibv5, but with a different set of steps. Then these methods will be called in Set.image method of windows module, like this.

pub(crate) fn image(self, image: ImageData) -> Result<(), Error> {
    // skipped...
    
    image_data::add_cf_dibv5(open_clipboard, image)
    image_data::add_png(image) // This is the new method.
}

This will also require having image library on Windows, so that we can take raw RGBA bytes and save it as PNG to the memory buffer before copying it.

This wouldn't require any changes to the public API, as far as I see.

I suppose I can close this issue now, as this is fixed.