获取JavaScript中的图像数据URL?

获取JavaScript中的图像数据URL?,javascript,image,firefox,greasemonkey,base64,Javascript,Image,Firefox,Greasemonkey,Base64,我有一个带有一些图像的常规HTML页面(只有常规的HTML标记)。我希望获得他们的内容,最好是base64编码,而不需要重新下载图像(即,它已经由浏览器加载,所以现在我想要内容) 我希望通过Greasemonkey和Firefox实现这一点。注意:只有当图像与页面来自同一域,或者具有crossOrigin=“anonymous”属性且服务器支持CORS时,此功能才有效。它也不会提供原始文件,而是重新编码的版本。如果需要与原始结果相同,请参阅 您需要创建具有正确尺寸的画布元素,并使用drawIm

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


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

注意:只有当图像与页面来自同一域,或者具有
crossOrigin=“anonymous”
属性且服务器支持CORS时,此功能才有效。它也不会提供原始文件,而是重新编码的版本。如果需要与原始结果相同,请参阅


您需要创建具有正确尺寸的画布元素,并使用
drawImage
功能复制图像数据。然后,您可以使用
toDataURL
函数获取具有base-64编码图像的data:url。请注意,图像必须完全加载,否则将返回一个空(黑色、透明)图像

应该是这样的。我从未编写过Greasemonkey脚本,因此您可能需要调整代码以在该环境中运行

function getBase64Image(img) {
    // Create an empty canvas element
    var canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;

    // Copy the image contents to the canvas
    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0);

    // Get the data-URL formatted image
    // Firefox supports PNG and JPEG. You could check img.src to
    // guess the original format, but be aware the using "image/jpg"
    // will re-encode the image.
    var dataURL = canvas.toDataURL("image/png");

    return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}

获取JPEG格式的图像在旧版本(大约3.5版)的Firefox上不起作用,因此如果你想支持它,你需要检查兼容性。如果不支持编码,它将默认为“image/png”。

此函数获取URL,然后返回图像BASE64

function getBase64FromImageUrl(url) {
    var img = new Image();

    img.setAttribute('crossOrigin', 'anonymous');

    img.onload = function () {
        var canvas = document.createElement("canvas");
        canvas.width =this.width;
        canvas.height =this.height;

        var ctx = canvas.getContext("2d");
        ctx.drawImage(this, 0, 0);

        var dataURL = canvas.toDataURL("image/png");

        alert(dataURL.replace(/^data:image\/(png|jpg);base64,/, ""));
    };

    img.src = url;
}
可以这样称呼:
getBase64FromImageUrl(“images/slbltxt.png”)

之后很久才会出现,但这里没有一个答案是完全正确的

在画布上绘制时,传递的图像将被解压缩+所有预乘。
导出时,将使用不同的算法对其进行解压缩或重新压缩,并取消相乘

在此过程中,所有浏览器和设备都会出现不同的舍入错误
(见附件)

因此,如果想要一个base64版本的图像文件,他们必须再次请求它(大部分时间它来自缓存),但这次是一个Blob

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

函数toDataURL(url,回调){ var xhr=new XMLHttpRequest(); xhr.open('get',url); xhr.responseType='blob'; xhr.onload=函数(){ var fr=new FileReader(); fr.onload=函数(){ 回调(this.result); }; fr.readAsDataURL(xhr.response);//异步调用 }; xhr.send(); } toDataURL(myImage.src,函数(dataURL){ result.src=dataURL; //现在只想说明传递到画布的结果并不相同 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-数据不同 });
Kaido使用fetch的答案的更现代版本是:

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

编辑:正如注释中指出的,这将返回一个指向本地系统中文件的对象url,而不是实际的DataURL,因此根据您的使用情况,这可能不是您所需要的


您可以查看以下使用fetch和实际数据URL的答案:

在HTML5中,最好使用此选项:

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

使用
onload
事件在加载后转换图像

已加载函数(img){
设c=document.createElement('canvas')
c、 getContext('2d').drawImage(img,0,0)
msg.innerText=c.toDataURL();
}
pre{wrap:break-word;宽度:500px;空白:pre-wrap;}

shiv/shim/sham 如果您的图像已加载(或未加载),此“工具”可能会派上用场:

Object.defineProperty
(
    HTMLImageElement.prototype,'toDataURL',
    {enumerable:false,configurable:false,writable:false,value:function(m,q)
    {
        let c=document.createElement('canvas');
        c.width=this.naturalWidth; c.height=this.naturalHeight;
        c.getContext('2d').drawImage(this,0,0); return c.toDataURL(m,q);
    }}
);
.. 但是为什么呢? 这样做的优点是使用“已加载”的图像数据,因此不需要额外的请求。另外,它允许最终用户(像您这样的程序员)决定COR和/或
mime类型
质量
-或者-您可以省略这些参数/参数,如MDN规范中所述

如果已加载此JS(在需要之前),则转换为
dataURL
非常简单:

例子
HTML
<img src="/yo.jpg" onload="console.log(this.toDataURL('image/jpeg'))">
GPU指纹识别
如果您担心位的“精确性”,那么您可以根据@kaido的回答更改此工具以满足您的需要。

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


虽然这似乎是可行的(除了返回中的unescaped/之外),但在对使用file_get_contents函数获得的文件进行base64_编码时,它不会创建与我从PHP获得的相同的base64字符串。这些图像看起来非常相似/相同,但Javascripted的图像更小,我希望它们完全相同。还有一件事:输入图像是一个小的(594字节),28x30 PNG,背景透明——如果这改变了什么的话。Firefox可能使用了不同的压缩级别,这会影响编码。此外,我认为PNG支持一些额外的标题信息,如注释,这将丢失,因为画布只获取像素数据。如果您需要完全相同,您可以使用AJAX获取文件并手动对其进行base64编码。它可能会使用映像的缓存版本,但这取决于服务器和浏览器配置,并且您将有请求开销来确定文件是否已更改。这就是为什么我一开始没有建议:-)不幸的是,据我所知,这是获取原始文件的唯一方法。@trusktr
drawImage
将一事无成,最终你会得到一个空白画布和结果图像。@johnsell这只是因为OP想要的是内容,而不是URL。如果要将替换(…)调用用作图像源,则需要跳过该调用。是否有方法将图像从外部
console.log(document.getElementById("someImgID").toDataURL());
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);
});