12Me21
12Me21

Reputation: 1169

How to get pasted images with transparency in Javascript

When detecting pasted images using event.clipboardData, the alpha channel is lost. Apparently this is because Windows stores images in the clipboard as 24-bit bitmaps.

I've heard that some applications store the transparency data of copied images separately, but I can't find out whether this can be accessed through clipboardData.

Here's a pasted image detector I wrote a while ago:
http://12Me21.github.io/paste/

Upvotes: 3

Views: 522

Answers (2)

YellowAfterlife
YellowAfterlife

Reputation: 3192

Here's what I found:

  • In all tests I've done, pasting pixels results in a single image/png blob in the clipboard, so there's not much you can do - it either works, or doesn't.

  • The behaviour is consistent between paste event, navigator.clipboard.read, and pasting into contenteditable.

  • Transparency is hopelessly hit and miss on Windows depending on how the data is copied:

    • from Paint.NET: opaque in both Chromium and Firefox.
    • from Krita: transparent in Firefox, opaque in Chromium.
    • from Aseprite: transparent in Chromium, opaque in Firefox.

    This is probably due to the aforementioned nightmare of clipboard formats on Windows.

  • Transparency works remarkably well on Linux - I have tested copying from Krita, Aseprite, and GIMP with Firefox and Chromium and all is well.

  • Specification does not say anything about discarding or not discarding alpha channel, perhaps making it implementation-defined in general.

A workaround is to also offer the user to provide their images via <input type="file" accept="image/*"/> and/or drag-and-drop events (for files), both of which are free of this issue (likely due to passing the file as-is).

Upvotes: 1

Nyerguds
Nyerguds

Reputation: 5629

I actually researched the subject of transparency on the Windows clipboard extensively, so while I'm not really experienced with javascript, I can help you along with the principles.

The clipboard works with a system of string IDs for their clipboard types, and you can put multiple such types on the clipboard simultaneously. In recent years, a lot of applications (including MS Office and Gimp) have started using the type "PNG" for transparent images, which will contain a raw byte stream with the bytes for a png image.

However, a much more commonly used one is the DIB format, which has clipboard ID "DeviceIndependentBitmap", and that one may be... problematic. Like the PNG one, it is a raw byte stream, but the actual file format is a bit of a mess. For more information about the DIB format, I advise you to read through this question and the answer I gave to it, and the Device Independent Bitmap specs and BITMAPINFOHEADER struct on MSDN. Long story short, it's a 32bpp RGB format that's abused as (and sometimes mistaken for) ARGB. I have no idea how plausible it is to parse DIB into a usable image in Javascript, though, but a lot of programs (including Google Chrome) seem to use it as only transparent image format they put on the clipboard when copying an image.

To fully support transparent pasting you'll probably need to support both the PNG and DIB formats (and, given the problems and controversies surrounding DIB, preferably in that order). This answer may give more information regarding the general method to sift through the clipboard and parse the PNG and DIB images, though it is C# code, and not Javascript.

Upvotes: 2

Related Questions