指定从FileReader readAsDataURL()返回的类型为PNG而不是TIFF? [英] Specify the type returned from FileReader readAsDataURL() as PNG and not TIFF?

查看:287
本文介绍了指定从FileReader readAsDataURL()返回的类型为PNG而不是TIFF?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到的图像已粘贴到内容可编辑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".

当我使用FileReaderreadAsDataURL获得该图像时,它返回的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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆