根据标题来看,是个很泛泛的说法。这只是一种大致的思路。web端需要操作图片的时候,有时需要的不仅仅是一个src,可能老大要你将获取到的图片转为二进制,以方便保存、上传、复制、粘贴等等。怎么做呢?
假设你有一个<img>标签,图片已经在网页中显示出来了,你能直接(同步的)取到它的二进制格式吗?答案好像是否定的。
我们知道图片的src,如果要加载一遍src需要等待,需要异步的回调。既然图片已经显示出来了,我们为何还要再去load一遍图片呢?我是这么想的,但是现实情况好像没这么完美。
第一种方法:Ajax请求图片可以返回Blob或ArrayBuffer。后用FileReader,可以读取Blob或者ArrayBuffer
function toDataUrl(url, callback) {
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob'; //设定返回数据类型为Blob
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function() {
callback(reader.result); //FileReader读取后的回调
}
reader.readAsDataURL(xhr.response); //xhr.response就是一个Blob,用FileReader读取
};
xhr.open('GET', url);
xhr.send();
}
用法:
toDataUrl('http://path/to/your/pic.png',function(dataUrl){
console.info(dataUrl); //dataUrl是base64格式
});
该方法很慢,两个回调函数。也需要浏览器兼容
第二种方法:图片加载后用canvas画出来,然后再toDataUrl
function toDataUrl(src, callback, outputFormat) {
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function() {
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat); //image/png, image/jpeg
callback(dataURL);
};
img.src = src;
}
方法执行完后,就等着GC自动回收img和canvas对象吧。
中间变量
有时候我们要关注这个过程的中间变量。比如第一种方法产生的Blob对象。