我理解目前在客户端<img />
对象中用JavaScript创建File
元素的常用技术就是这样的。
(File
对象将来自文件拖放处理程序或<input type="file" />
change
事件。)
function showImageFile( file: File ): void {
let rdr = new FileReader();
rdr.readAsDataURL( file );
rdr.onloadend = function() {
let img = document.createElement('img');
img.src = rdr.result;
document.body.appendChild( img );
};
}
我不喜欢这个 - 将一个多兆字节的图像序列化为base64编码的字符串(因此在现有的File
对象上使用1.3倍的内存)以及产生反序列化字符串的成本的概念回到<img />
元素 - 最终这将导致至少3个图像数据实例存在于内存中。这对我来说似乎非常浪费和低效,并且JavaScript应用程序已经因过多的内存消耗而导致错误。
我注意到,对于<video>
和<audio>
元素(HTMLMediaElement
),MDN建议做这样的事情:
function showVideoFile( file: File ): void {
let video = document.createElement('video');
video.srcObject = URL.createObjectURL( file ); // createObjectURL creates a URI alias to the existing file instance in-memory
}
(需要注意的是,如果srcObject
被取代或者video
元素被移除,之前的objectURL
必须使用revokeObjectURL
手动释放。
有没有办法为<img />
做同样的事情? (我没有看到srcObject
上的HTMLImageElement
属性和HTMLImageElement
不是来自HTMLMediaElement
)。不幸的是,在线搜索“没有数据URI的javascript图像文件”只会返回有关readAsDataURL
的页面,这与我想要的相反。
你设置了它... src
。
document.getElementById('file').onchange = function () {
if (this.files.length !== 0) {
var img = new Image();
img.src = URL.createObjectURL(this.files[0]);
document.body.appendChild(img);
}
};
<input type="file" id="file" accept="image/*" />
在谷歌的黑暗和肮脏的信息挖掘中牺牲了更多的时间后,我在2014年12月的文章http://bytes.schibsted.com/the-magic-of-createobjecturl/中找到了一块煤,它说HTMLImageElement
的src
属性确实接受了一个对象URI(p!)
MDN也在他们的网站上报道了它,尽管有点埋没:https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications#Example_Using_object_URLs_to_display_images
简而言之,我的showImageFile
函数可以像这样更新:
function showImageFile( file: File ): void {
let objectURI = URL.createObjectURL( file ); // looks like "blob:http://mywebsite/{guid}"
let img = document.createElement('img');
img.src = objectURI ;
document.body.appendChild( img );
}
或者如果img
元素将被重用:
var img: HTMLImageElement;
function showImageFile( file: File ): void {
let oldSrc = img.src;
let objectURI = URL.createObjectURL( file );
img.src = objectURI;
if( oldSrc ) URL.revokeObjectURL( oldSrc );
}