HTML5文件API之图片预览

13年前
图片上传在当今的Web应用中是一个非常常用的功能,如果不需要在上传前进行图片预览则可以简单的使用HTML+Javascript来实现,但如果一定要在上传之前提供图片预览功能则需要求助于Flash来实现。不过,随着HTML5 File API的诞生这一状况终于有了改观,本文将介绍如何使用HTML5 File API快速的实现图片预览功能。

  浏览器支持情况

  本文实现的功能在以下浏览器中经过测试:IE8、Firefox3.6、Chrome6.0、Opera10、Safari4。其中Firefox3.6与Chrome6.0已经实现了该标准(虽然并没有完全遵循标准),其他浏览器均未实现。关于具体的兼容性问题,后文将详细说明。

  文件选择与获取

  如今最常见的文件选择方式是使用File Input元素,用户通过该元素打开本机文件对话框寻找并选择相应的文件,不过随着HTML5 Drag Drop API的出现又增加了一种新的方式-用户可以直接将本机的文件拖拽到Web页面中。

  方式一<input type=”file”>

<input id="fileSel" type="file" onchange="handleFiles(this.files)"> 
<script type="text/javascript"> 
 
//获取用户选择的文件 
 
function handleFiles(files){ 
 
    //遍历files并处理 
 

 
</script>

  方式二 Drag & Drop

<div id="fileDropRegion">将文件拖拽到此</div> 
<script type="text/javascript"> 
 
//获取用户选择的文件 
 
var dr = document.getElementById('fileDropRegion'); 
 
dr.addEventListener("drop",function(e){ 
     e.stopPropagation();  
     e.preventDefault();   
 
     var dt = e.dataTransfer;   
 
     //获取文件数组 
     var files = dt.files; 
     handleFiles(files);  
},false); 
 
function handleFiles(files){ 
 
    //遍历files并处理 
 

 
</script>

  文件读入与展示

  通过上文中的方法我们获取到了用户选择的文件数组,接下来就该操作其中的每一个文件了,如HTML5 File API描述的那样,每个文件对象应该包含以下属性:

readonly attribute DOMString name;           //The name of the file.

readonly attribute unsigned long long size; //Represents the size of the Blob object in bytes.

readonly attribute DOMString type;            //The media type of the Blob

readonly attribute DOMString url;              //The URL representing the Blob object.

  如果是上传图片则可以通过type属性来进行图片格式过滤,并可以通过size属性来控制图片大小。对于这些属性,Firefox与Chrome的实现情况是出奇的一致,均只支持name、size和type属性。

function handleFiles(files){ 
 
    //遍历files并处理 
 
    for (var i = 0; i < files.length; i++) {  
    var file = files[i];  
    var imageType = /image.*/;   
 
        //通过type属性进行图片格式过滤 
    if (!file.type.match(imageType)) {  
      continue;  
    }   
 
        //读入文件 
 
    }  
 

 
</script>

  此外,HTML5 File API中还定义了一个BlobReader,通过它可以使用各种不同的方式读入文件并且可以监听和处理读取文件过程中的各个状态。不过在Firefox与Chrome的实现中,并没有这样一个BlobReader,取而代之的是FileReader,拥有与BlobReader相同的方法和事件。

// async read methods

void readAsArrayBuffer(in Blob blob);

void readAsBinaryString(in Blob blob);

void readAsText(in Blob blob, [Optional] in DOMString encoding);

void readAsDataURL(in Blob blob);

// event handler attributes

attribute Function onloadstart;

attribute Function onprogress;

attribute Function onload;

attribute Function onabort;

attribute Function onerror;

attribute Function onloadend;

  以上4个读取文件的方式均是异步的,需要注册监听对应的事件来处理文件,而与图片预览相关的方法是readAsDataURL,该方法会将图片文件内容转换成dataURI的格式,而该格式是可以直接在浏览器中显示的。

function handleFiles(files){ 
 
    //遍历files并处理 
 
    for (var i = 0; i < files.length; i++) {  
    var file = files[i];  
    var imageType = /image.*/;   
 
        //通过type属性进行图片格式过滤 
    if (!file.type.match(imageType)) {  
      continue;  
    }   
 
        //读入文件 
 
    var reader = new FileReader();  
    reader.onload = function(e){ 
 
            //e.target.result返回的即是图片的dataURI格式的内容 
 
            var imgData = e.target.result, 
 
                img = document.createElement('img'); 
 
            img.src = imgData; 
 
            //展示img 
 
    } 
    reader.readAsDataURL(file);  
    }   
 

 
</script>

  通过以上几步便简单的实现了图片的上传前的预览功能,具体的效果请在Firefox或Chrome下打开此页面

  参考资料

  HTML5 File API

  Using files from web applications