Answers:
注意:仅当图像与页面来自同一域或具有crossOrigin="anonymous"
属性并且服务器支持CORS时,此方法才有效。它也不会给您原始文件,而是一个重新编码的版本。如果您需要与原始结果相同的结果,请参见Kaiido的答案。
您将需要创建具有正确尺寸的canvas元素,并使用drawImage
函数复制图像数据。然后,您可以使用该toDataURL
函数获取数据:具有以64为基数编码的图像的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格式的图像在Firefox的较旧版本(约3.5版)上不起作用,因此,如果要支持该功能,则需要检查兼容性。如果不支持编码,则默认为“ image / png”。
drawImage
不会执行任何操作,最终将得到空白画布和生成的图像。
该函数获取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")
img.src =
之后img.onload =
,因为在某些浏览器(例如Opera)中,该事件不会发生。
getBase64FromImageUrl(url)
,并img.onload = function ()
在退出IMG无法访问,垃圾收集。除了IE 6/7以外,都可以。
不久以后,但是这里没有答案是完全正确的。
当在画布上绘制时,传递的图像是未压缩+所有预乘的。
导出时,其未压缩或使用其他算法重新压缩,并且未相乘。
在此过程中,所有浏览器和设备都会发生不同的舍入错误
(请参阅Canvas指纹识别)。
因此,如果要使用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">
XMLHttpRequest cannot load data:image/jpeg;base64,/9j/4AA ... /2Q==. Invalid response. Origin 'https://example.com' is therefore not allowed access.
kaiido使用fetch回答的更现代版本是:
function toObjectUrl(url) {
return fetch(url)
.then((response)=> {
return response.blob();
})
.then(blob=> {
return URL.createObjectURL(blob);
});
}
https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch
编辑:正如评论中指出的那样,这将返回一个指向您本地系统中文件的URL,而不是实际的DataURL,因此根据您的用例,这可能不是您所需要的。
您可以查看以下答案以使用访存和实际dataURL:https ://stackoverflow.com/a/50463054/599602
URL.revokeObjectURL()
如果您使用此方法的应用程序运行时间较长,请不要忘记调用它,否则您的内存将变得混乱。
如果您的图像已经加载(或未加载),则此“工具”可能会派上用场:
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);
}}
);
这具有使用“已加载”图像数据的优点,因此不需要额外的请求。的方法,另外它可以让最终用户(程序员喜欢你)决定CORS和/或mime-type
与quality
-或-您可以将这些参数/中所描述的参数MDN规范在这里。
如果您已加载此JS(在需要它之前),则转换为dataURL
非常简单:
HTML
<img src="/yo.jpg" onload="console.log(this.toDataURL('image/jpeg'))">
JS
console.log(document.getElementById("someImgID").toDataURL());
如果您担心位的“准确性”,则可以按照@Kaiido的回答提供的方法更改此工具以适合您的需求。
onload
加载后使用事件转换图像
在HTML5中,最好使用以下命令:
{
//...
canvas.width = img.naturalWidth; //img.width;
canvas.height = img.naturalHeight; //img.height;
//...
}