【问题标题】:How to get pasted images with transparency in Javascript如何在Javascript中获得透明的粘贴图像
【发布时间】:2018-05-07 15:56:17
【问题描述】:
使用event.clipboardData 检测粘贴的图像时,Alpha 通道丢失。显然这是因为 Windows 将剪贴板中的图像存储为 24 位位图。
听说有些应用把复制图片的透明度数据单独保存了,不知道是否可以通过clipboardData访问。
这是我前段时间写的一个粘贴图像检测器:
http://12Me21.github.io/paste/
【问题讨论】:
标签:
javascript
windows
image
clipboard
paste
【解决方案1】:
我实际上在 Windows 剪贴板上广泛研究了透明度的主题,所以虽然我对 javascript 没有真正的经验,但我可以帮助你了解这些原则。
剪贴板使用其剪贴板类型的字符串 ID 系统,您可以同时在剪贴板上放置多个此类类型。近年来,许多应用程序(包括 MS Office 和 Gimp)已经开始使用“PNG”类型来表示透明图像,其中将包含一个原始字节流以及 png 图像的字节。
不过,更常用的一种是 DIB 格式,它的剪贴板 ID 为“DeviceIndependentBitmap”,而这种格式可能...有问题。和 PNG 一样,它是一个原始字节流,但实际的文件格式有点乱。有关 DIB 格式的更多信息,我建议您通读 this question and the answer I gave to it,以及 MSDN 上的 Device Independent Bitmap specs 和 BITMAPINFOHEADER struct。长话短说,它是一种 32bpp RGB 格式,被滥用为(有时被误认为是)ARGB。不过,我不知道在 Javascript 中将 DIB 解析为可用图像有多合理,但是许多程序(包括 Google Chrome)似乎将其用作复制图像时放在剪贴板上的唯一透明图像格式。
要完全支持透明粘贴,您可能需要同时支持 PNG 和 DIB 格式(并且,鉴于 DIB 存在的问题和争议,最好按此顺序)。 This answer 可能会提供有关筛选剪贴板和解析 PNG 和 DIB 图像的一般方法的更多信息,尽管它是 C# 代码,而不是 Javascript。
【解决方案2】:
这是我发现的:
-
在我所做的所有测试中,粘贴像素会在剪贴板中生成单个图像/png blob,因此您无能为力 - 它要么有效,要么无效。
-
paste 事件、navigator.clipboard.read 和粘贴到 contenteditable 之间的行为是一致的。
-
根据数据的复制方式,在 Windows 上的透明度是无可救药的:
- 来自 Paint.NET:在 Chromium 和 Firefox 中都是不透明的。
- 来自 Krita:在 Firefox 中透明,在 Chromium 中不透明。
- 来自 Aseprite:在 Chromium 中透明,在 Firefox 中不透明。
这可能是由于前面提到的 Windows 上剪贴板格式的噩梦。
-
透明度在 Linux 上运行得非常好 - 我已经用 Firefox 和 Chromium 测试了从 Krita、Aseprite 和 GIMP 复制,一切都很好。
-
Specification 没有说任何关于丢弃或不丢弃 alpha 通道的内容,也许通常是实现定义的。
一种解决方法是还让用户通过<input type="file" accept="image/*"/> 和/或拖放事件(对于文件)提供他们的图像,这两者都没有这个问题(可能是由于将文件传递为-是)。