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