指定从 FileReader readAsDataURL() 返回的类型为 PNG 而不是 TIFF?
Specify the type returned from FileReader readAsDataURL() as PNG and not TIFF?
我得到一张图像,该图像已粘贴到可编辑的内容 div 中,并且在粘贴过程中 Clipboard
中列出的 types
包括“image/png
”和“image/tiff
”。
当我使用 FileReader
和 readAsDataURL
得到该图像时 base64
图像字符串 returns 是 TIFF
, "data:image/tiff,
”。
有没有办法指定给FileReader
到return一个PNG
,“data:image/png
”?
相关问题。
你不知道。
FileReader.readAsDataURL()
仅将传递的 Blob 中保存的二进制数据转换为 base64 字符串,不进行任何其他转换。
它只会将相应的 MIME header 添加到它认为此数据的任何内容(此检查首先针对 Blob 的 type
,然后可能针对 magic-numbers),但您不能强制它将数据转换为其他内容。
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 界面,你运气不好。
即使 Grab 实用程序确实在剪贴板中保存了一个 png 文件,Safari 还是选择显示 tiff 原始数据。
您可以在开发人员的网络面板中检查此断言,您会在其中看到图像被提取为 image/tiff。
虽然支持 DataTransferItem 接口的浏览器可以检索剪贴板中附加的 png 文件,但我们希望 Safari 尽快实现此接口。
因此,将此 TIFF 图像转换为 png 图像的一种方法是通过 canvas 元素:
// 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>
我得到一张图像,该图像已粘贴到可编辑的内容 div 中,并且在粘贴过程中 Clipboard
中列出的 types
包括“image/png
”和“image/tiff
”。
当我使用 FileReader
和 readAsDataURL
得到该图像时 base64
图像字符串 returns 是 TIFF
, "data:image/tiff,
”。
有没有办法指定给FileReader
到return一个PNG
,“data:image/png
”?
相关问题
你不知道。
FileReader.readAsDataURL()
仅将传递的 Blob 中保存的二进制数据转换为 base64 字符串,不进行任何其他转换。
它只会将相应的 MIME header 添加到它认为此数据的任何内容(此检查首先针对 Blob 的 type
,然后可能针对 magic-numbers),但您不能强制它将数据转换为其他内容。
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 界面,你运气不好。
即使 Grab 实用程序确实在剪贴板中保存了一个 png 文件,Safari 还是选择显示 tiff 原始数据。
您可以在开发人员的网络面板中检查此断言,您会在其中看到图像被提取为 image/tiff。
虽然支持 DataTransferItem 接口的浏览器可以检索剪贴板中附加的 png 文件,但我们希望 Safari 尽快实现此接口。
因此,将此 TIFF 图像转换为 png 图像的一种方法是通过 canvas 元素:
// 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>