我有一个带有一些图像的常规HTML页面(只是常规的<img /> HTML标签)。我想得到他们的内容,base64编码最好,而不需要重新下载图像(即。它已经被浏览器加载,所以现在我想要的内容)。

我希望通过Greasemonkey和Firefox实现这一目标。


当前回答

这就是你需要阅读的全部内容。

https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsBinaryString

var height = 200;
var width  = 200;

canvas.width  = width;
canvas.height = height;

var ctx = canvas.getContext('2d');

ctx.strokeStyle = '#090';
ctx.beginPath();
ctx.arc(width/2, height/2, width/2 - width/10, 0, Math.PI*2);
ctx.stroke();

canvas.toBlob(function (blob) {
  //consider blob is your file object

  var reader = new FileReader();

  reader.onload = function () {
    console.log(reader.result);
  }

  reader.readAsBinaryString(blob);
});

其他回答

在HTML5中最好使用这个:

{
//...
canvas.width = img.naturalWidth; //img.width;
canvas.height = img.naturalHeight; //img.height;
//...
}

它的2022年,我更喜欢使用现代createImageBitmap()而不是onload事件。

*注意:图像应该是相同的来源或CORS启用

async function imageToDataURL(imageUrl) { let img = await fetch(imageUrl); img = await img.blob(); let bitmap = await createImageBitmap(img); let canvas = document.createElement("canvas"); let ctx = canvas.getContext("2d"); canvas.width = bitmap.width; canvas.height = bitmap.height; ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height); return canvas.toDataURL("image/png"); // image compression? // return canvas.toDataURL("image/png", 0.9); }; (async() => { let dataUrl = await imageToDataURL('https://en.wikipedia.org/static/images/project-logos/enwiki.png') wikiImg.src = dataUrl; console.log(dataUrl) })(); <img id="wikiImg">

kaiido使用fetch的更现代版本的答案是:

function toObjectUrl(url) {
  return fetch(url)
      .then((response)=> {
        return response.blob();
      })
      .then(blob=> {
        return URL.createObjectURL(blob);
      });
}

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

编辑:正如评论中指出的那样,这将返回一个指向本地系统中的文件的对象url,而不是实际的DataURL,因此根据您的用例,这可能不是您所需要的。

您可以查看下面的答案来使用fetch和一个实际的dataURL: https://stackoverflow.com/a/50463054/599602

这就是你需要阅读的全部内容。

https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsBinaryString

var height = 200;
var width  = 200;

canvas.width  = width;
canvas.height = height;

var ctx = canvas.getContext('2d');

ctx.strokeStyle = '#090';
ctx.beginPath();
ctx.arc(width/2, height/2, width/2 - width/10, 0, Math.PI*2);
ctx.stroke();

canvas.toBlob(function (blob) {
  //consider blob is your file object

  var reader = new FileReader();

  reader.onload = function () {
    console.log(reader.result);
  }

  reader.readAsBinaryString(blob);
});

很久以后,这里没有一个答案是完全正确的。

当在画布上绘制时,传递的图像是未压缩的+所有预相乘。 当导出时,它用不同的算法解压缩或重压缩,并且不相乘。

在这个过程中,所有浏览器和设备都有不同的舍入错误 (见画布指纹)。

因此,如果有人想要base64版本的图像文件,他们必须再次请求它(大多数时候它将来自缓存),但这次是作为一个Blob。

然后,您可以使用FileReader将其作为ArrayBuffer或dataURL读取。

function toDataURL(url, callback){ var xhr = new XMLHttpRequest(); xhr.open('get', url); xhr.responseType = 'blob'; xhr.onload = function(){ var fr = new FileReader(); fr.onload = function(){ callback(this.result); }; fr.readAsDataURL(xhr.response); // async call }; xhr.send(); } toDataURL(myImage.src, function(dataURL){ result.src = dataURL; // now just to show that passing to a canvas doesn't hold the same results var canvas = document.createElement('canvas'); canvas.width = myImage.naturalWidth; canvas.height = myImage.naturalHeight; canvas.getContext('2d').drawImage(myImage, 0,0); console.log(canvas.toDataURL() === dataURL); // false - not same data }); <img id="myImage" src="https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png" crossOrigin="anonymous"> <img id="result">