问题描述
我得到的图像已粘贴到内容可编辑div中,并且在粘贴期间,Clipboard
中列出的types
中包括"image/png
"和"image/tiff
".
I'm getting an image that has been pasted into the content editable div and during paste the types
in listed in the Clipboard
include "image/png
" and "image/tiff
".
当我使用FileReader
和readAsDataURL
获得该图像时,它返回的base64
图像字符串是TIFF
,"data:image/tiff,
".
When I get that image using a FileReader
and readAsDataURL
the base64
image string it returns is a TIFF
, "data:image/tiff,
".
是否可以指定FileReader
以返回PNG
,"data:image/png
"?
Is there a way to specify to the FileReader
to return a PNG
, "data:image/png
"?
相关问题这里.
推荐答案
您不知道.FileReader.readAsDataURL()
仅将传递的Blob中保存的二进制数据转换为base64字符串,而不进行任何其他转换.
它只会将相应的MIME标头添加到它认为该数据是的任何位置(此检查首先针对Blob的type
,然后可能针对幻数进行),但是您不能强制其将数据转换为某种东西别的.
You don't.FileReader.readAsDataURL()
only converts the binary data held in the passed Blob to a base64 string, it doesn't do any other conversion.
It will only prepend the corresponding MIME header to whatever it thinks this data is (this check is first done against the Blob's type
, and then probably against magic-numbers), but you can't force it to convert the data to something else.
const fr = new FileReader();
const fakeGif = new Blob(['foo'], {type:'image/gif'});
fr.onload = onload;
fr.readAsDataURL(fakeGif);
function onload(){
console.log(fr.result); // with image/gif MIME
console.log(atob(fr.result.split(',')[1])) // still just "foo"...
}
根据您的情况,由于Safari仍然不支持 DataTransferItem 接口,您很不走运.
Now to your case, since Safari still doesn't support the DataTransferItem interface, you are out of luck.
尽管 Grab 实用程序确实将png文件保存在剪贴板中,但Safari选择显示tiff原始数据.
Even though Grab utility does save a png File in the clipboard, Safari chose to display the tiff raw data.
您可以在开发人员的网络"面板中检查此断言,在该面板中,您会看到图像以图像/tiff的形式获取.
You can check this assertion in your dev's Network panel, where you will see that the image is fetched as image/tiff.
虽然确实支持DataTransferItem接口的浏览器可以检索剪贴板中附加的png文件,所以我们希望Safari尽快实现此接口.
Browsers that do support DataTransferItem interface can retrieve the png file attached in the clipboard though, so let's hope Safari implement this interface soon enough.
因此,将此TIFF图像转换为png的一种方法是遍历canvas元素:
So one way to convert this TIFF image to a png one, is to go through a canvas element:
// an Array to hold pasted Files
var files = [];
// We start by checking if the browser supports the
// DataTransferItem interface. If not, we need to create a
// contenteditable element that catches all pasted data
if (!window.DataTransferItem) {
var pasteCatcher = document.createElement("div");
pasteCatcher.setAttribute("contenteditable", "");
// We can hide the element and append it to the body,
pasteCatcher.style.opacity = 0.5;
document.body.appendChild(pasteCatcher);
// as long as we make sure it is always in focus
pasteCatcher.focus();
document.addEventListener("click", function() {
pasteCatcher.focus();
});
}
// Add the paste event listener
window.addEventListener("paste", pasteHandler);
/* Handle paste events */
function pasteHandler(e) {
// We need to check if event.clipboardData is supported (Chrome)
if (e.clipboardData) {
// Get the items from the clipboard
var items = e.clipboardData.items || e.clipboardData.files;
itemcount = items.length;
if (itemcount) {
// Loop through all items, looking for any kind of image
for (var i = 0; i < items.length; i++) {
getItem(items[i]);
}
} else {
// This is a cheap trick to make sure we read the data
// AFTER it has been inserted.
setTimeout(checkInput, 1);
}
// If we can't handle clipboard data directly (Firefox),
// we need to read what was pasted from the contenteditable element
} else {
console.log("checking input");
// This is a cheap trick to make sure we read the data
// AFTER it has been inserted.
setTimeout(checkInput, 1);
}
}
/* For browsers that support DataTransferItem interface */
function getItem(item) {
if (item.type.indexOf("image") !== -1) {
// We need to represent the image as a file,
var blob = item instanceof Blob ? item : item.getAsFile();
// save the File for later use if needed
files.push(blob);
// and use a URL or webkitURL (whichever is available to the browser)
// to create a temporary URL to the object
var URLObj = window.URL || window.webkitURL;
var source = URLObj.createObjectURL(blob);
// The URL can then be used as the source of an image
createImage(source);
}
}
/* For older browsers */
/* Parse the input in the paste catcher element */
function checkInput() {
// Store the pasted content in a variable
var child = pasteCatcher.childNodes[0];
if (child) {
// If the user pastes an image, the src attribute
// will represent the image as a base64 encoded string.
if (child.tagName === "IMG") {
getPngFromIMG(child, function(blob) {
// Clear the inner html to make sure we're always
// getting the latest inserted content
pasteCatcher.innerHTML = "";
// save the png blob in our list
files.push(blob);
createImage(URL.createObjectURL(blob));
});
}
}
}
function getPngFromIMG(img, callback) {
if (img.naturalWidth) // if already loaded
draw();
else
img.onload = draw;
function draw() {
var canvas = document.createElement('canvas');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
canvas.getContext('2d').drawImage(img, 0, 0);
canvas.toBlob(callback);
}
}
/* Creates a new image from a given source */
function createImage(source) {
var pastedImage = new Image();
pastedImage.onload = function(e) {
loadImage.src = e.target.src;
}
pastedImage.src = source;
}
btn.onclick = function() {
console.log(files);
}
<textarea id="pasteArea" placeholder="Paste Image Here"></textarea>
<img id="loadImage" />
<button id="btn">do something with pasted files</button>
这篇关于指定从FileReader readAsDataURL()返回的类型为PNG而不是TIFF?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!