javascript和HTML5上傳圖片以前實現預覽效果

一:FileList對象與file對象php

     FileList對象表示用戶選擇的文件列表,在HTML4中,file控件內只容許放置一個文件,可是到了HTML5中,經過添加multiple屬性,file控件內容許一次放置多個文件,控件內的每個用戶選擇的文件都是一個file對象,而FileList對象是file對象的列表;html

好比以下代碼:html5

選擇文件<input type="file" id="file" multiple size="80"/>
<input type="button" onclick="ShowFileName();" value="文件上傳"/>

咱們能夠按住ctrl鍵選擇多個文件;web

JS代碼以下:chrome

function ShowFileName() {
    var files = document.getElementById("file").files;
    for(var i = 0; i < files.length; i+=1) {
        var file = files[i];
        console.log(file);
        console.log(file.name);
     }
}

咱們先打印下file對象有哪些屬性,在safari截圖以下:數據庫

如上圖能夠看到有文件名(name)屬性,文件大小(size)屬性,最後修改時間,還有type屬性等;canvas

二:Blob對象瀏覽器

在HTML5中,新增一個Blob對象,表明原始二進制數據,咱們上面提到的file對象也繼承了這個Blob對象;安全

Blob對象有2個屬性,size屬性表示一個Blob對象的字節長度,type屬性表示Blob的MIME類型,若是是未知類型,則返回一個空字符串。服務器

以下代碼:

選擇文件<input type="file" id="file" multiple size="80" accept="image/*"/>
<input type="button" onclick="ShowFileType();" value="顯示文件信息"/>
文件字節長度:<span id="size"></span><br/>
文件類型:<span id="type"></span>

JS代碼以下:

function ShowFileType() {
    var file = document.getElementById("file").files[0];
    var size = document.getElementById("size");
    var type = document.getElementById("type");
    // 顯示文件字節長度
    size.innerHTML = file.size;
    // 顯示文件類型
    type.innerHTML = file.type;
    console.log(file);
}

咱們打印出file,以下圖所示:

三:FileReader對象

    FileReader對象有5種方法,其中四種用於讀取文件,另外一種用來讀取過程當中斷,須要注意的是:不管讀取成功與失敗,方法並不會返回讀取結果,而是將結果保存在result屬性中。此對象也是異步的。

FileReader對象的方法以下:

    readAsBinaryString(file): 這個方法將blob對象或文件中的數據讀取爲二進制字符串,一般咱們將它傳送到服務器端,服務器端能夠經過這段字符串存儲文件。

    readAsText(file,encoding): 以純文本形式讀取文件,將讀取到的文本保存在result屬性中,第二個參數用於指定編碼類型,可選的。

    readAsDataURL(file): 讀取文件並將文件以數據URL的形式保存在result屬性中。

    readAsArrayBuffer(file): 讀取文件並將一個包含文件內容的ArrayBuffer保存在result屬性中。

FileReader對象的事件以下:

    onabort:  數據讀取中斷時觸發

    onerror: 數據讀取出錯時觸發

    onloadstart: 數據讀取開始時觸發

    onprogress: 數據讀取中

    onload: 數據讀取成功完成時觸發

    onloadend: 數據讀取完成時觸發,不管成功或失敗。

咱們能夠先看看demo,如何使用FileReader對象中前面三個方法;注意:fileReader對象讀取的數據都保存在result中,以下代碼:

<p>
    <label>請選擇一個文件:</label>
    <input type="file" id="file" />
    <input type="button" value="讀取圖像" onclick = "readAsDataURL()"/>
    <input type="button" value="讀取二進制數據" onclick = "readAsBinaryString()"/>
    <input type="button" value="讀取文本文件" onclick = "readAsText()"/>
</p>
<div id="result"></div>

JS代碼以下:

<script>
    var result = document.getElementById("result");
    if(typeof FileReader == 'undefined') {
        result.innerHTML = "抱歉,你的瀏覽器不支持FileReader";
    }
    // 將文件以Data URL形式進行讀入頁面
    function readAsDataURL(){
        // 檢查是否爲圖像類型
        var simpleFile = document.getElementById("file").files[0];
        if(!/image\/\w+/.test(simpleFile.type)) {
            alert("請確保文件類型爲圖像類型");
            return false;
        }
        var reader = new FileReader();
        // 將文件以Data URL形式進行讀入頁面
        reader.readAsDataURL(simpleFile);
        reader.onload = function(e){
            console.log(this.result);
            result.innerHTML = '<img src="'+this.result+'" alt=""/>';
        }
    }
    // 將文件以二進制形式讀入頁面
    function readAsBinaryString(){
        // 檢查是否爲圖像類型
        var simpleFile = document.getElementById("file").files[0];
        if(!/image\/\w+/.test(simpleFile.type)) {
            alert("請確保文件類型爲圖像類型");
            return false;
        }
        var reader = new FileReader();
        // 將文件以二進制形式進行讀入頁面
        reader.readAsBinaryString(simpleFile);
        reader.onload = function(e){
            // 在頁面上顯示二進制數據
            result.innerHTML = this.result;
        }
    }
    // 將文件以文本形式讀入頁面中
    function readAsText(){
        var simpleFile = document.getElementById("file").files[0];
        var reader = new FileReader();
        // 將文件以文本形式讀入頁面中
        reader.readAsText(simpleFile);
        reader.onload = function(e){
            result.innerHTML = this.result;
        }
    }
</script>

如上代碼,若是須要演示的話,能夠複製代碼到文本編輯器去,預覽下便可,這裏就不截圖了;可是如上代碼,在safari瀏覽器就不支持了~   截圖以下:

四:btoa方法與atob方法

在HTML5中,btoa方法與atob方法來支持base64編碼,b能夠被理解爲一串二進制數據,a能夠被理解爲一個ASCLL碼字符串,btoa的使用方法以下:

    var result = window.btoa(data);

該方法用於將一串字符串進行base64編碼處理,該方法使用一個參數,參數值由一串二進制數據組成的Unicode字符串,該方法返回編碼後的base64格式的字符串。

atob方法使用以下所示:

    var result = window.atob(data);

該方法用於將一串通過base64編碼後的base64格式的字符串進行解碼處理,該方法使用一個參數,參數值爲一串通過base64編碼後的字符串,方法返回通過解碼後的一串由二進制數據組成的Unicode字符串;

瀏覽器支持:firefox,chrome,opera10.5+及IE10+

何時使用btoa方法呢?

當服務器端數據庫中直接保存了是圖片的二進制數據及圖片文件的格式時,當咱們須要根據此二進制數據來渲染圖片的時候很是有用;以下代碼:

<p>
    <label>請選擇一個文件:</label>
    <input type="file" id="file"/>
    <input type="button" value="讀取圖像" onclick = "readPicture()" id="btnReadPicture"/>
</p>
<div id="result"></div>

JS代碼以下:

if(typeof FileReader == 'undefined') {
    result.innerHTML = "抱歉,你的瀏覽器不支持FileReader";
}
function readPicture(){
    // 檢查是否爲圖像類型
    var simpleFile = document.getElementById("file").files[0];
    if(!/image\/\w+/.test(simpleFile.type)) {
        alert("請確保文件類型爲圖像類型");
        return false;
    }
    var reader = new FileReader();
    // 將文件以二進制文件讀入頁面中
    reader.readAsBinaryString(simpleFile);
    reader.onload = function(f){
        var result = document.getElementById("result");
        var src = "data:" + simpleFile.type + ";base64," + window.btoa(this.result);
        result.innerHTML = '<img src ="'+src+'"/>';
    }
}

當咱們選擇一張圖像的時候,點擊讀取圖像按鈕便可生成一張圖片,雖然此方法咱們還可使用咱們上面介紹的readAsDataURL的方法也能夠直接讀取圖像,可是當服務器中直接是保存的是二進制文件的話,咱們能夠直接使用btoa此方法生成圖片便可;

下面咱們能夠看看atob的demo以下:

咱們可使用canvas來繪製一張圖片後,點擊上傳圖片按鈕後,首先經過canvas元素的toDataURL()方法獲取該圖片的url地址,最後獲取該URL地址中的base64格式的字符串,最後使用atob方法將其解碼爲一串二進制數據,並將該二進制數據提交到服務器端;以下代碼:

<input type="button" value="上傳圖片" onclick="imgSave()"/><br/>
<canvas id="canvas" width="400" height="300"></canvas>

JS代碼以下:

<script>
    var canvas;
    function draw(id) {
         canvas = document.getElementById(id);
        var context = canvas.getContext('2d');
        context.fillStyle = 'rgb(0,0,255)';
        context.fillRect(0,0,canvas.width,canvas.height);
        context.fillStyle = 'rgb(255,255,0)';
        context.fillRect(10,20,50,50);
    }
    draw('canvas');
    function imgSave(){
        var data = canvas.toDataURL("image/png");
        data = data.replace("data:image/png;base64,","");
        var xhr = new XMLHttpRequest();
        xhr.open("POST","uploadImg.php");
        xhr.send(window.atob(data));
    }
</script>

uploadImg.php本身寫;

下面咱們來作一個本地圖片上傳前預覽效果,可是safari不支持,因此在作移動端的同窗可能很差了,特別是在IOS6下就不支持哦,應該還有其餘辦法能夠解決的,咱們能夠看看百度的插件,網址以下:

http://fex.baidu.com/webuploader/demo.html

以前我是作了一個上傳本地圖片以前預覽效果,以下連接:

http://www.cnblogs.com/tugenhua0707/p/3568134.html

今天爲了學習FileReader,咱們能夠再來學習下;以前的本地上傳圖片預覽的話,不支持IE10+, 且把頁面放在服務器端在IE下會有bug,以下所示:

如上所示,在IE下 這個方法  document.selection.createRange() 不支持,所以爲了修復這個bug和在IE10+以上的話,今天又特地研究了下, 在file控件下獲取焦點狀況下 document.selection.createRange() 將會拒絕訪問,因此咱們要失去下焦點。咱們能夠再加一句代碼就能夠支持了 file.blur();

IE10+的bug的話,咱們可使用html5的上面介紹的文件API來解決,先判斷是否是IE,若是是的話,且小於10的話,使用濾鏡的方法解決圖片上傳的問題,若是是其餘瀏覽器的話,就使用html5的文件上傳方法;可是safari沒有處理好,緣由是safari不支持html5的fileReader的API,因此若是在移動端開發的圖片,若是須要兼容IOS6和6+的話,請注意一下,並不支持~ 固然若是你們有更好的方案來支持IOS6的話,請留言,能夠一塊兒總結,一塊兒學習~

五:上傳圖片以前預覽效果demo(Safari不兼容)

 1. 在標準瀏覽器下(IE10+)使用HTML5中文件API便可解決上傳圖片前預覽效果;在這裏有2中方案能夠解決,第一種是使用文件API,以下代碼:

function html5Reader(file) {
    var file = file.files[0];
    var reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = function(e){
        var pic = document.getElementById("img");
        pic.src=this.result;
    }
}

2. 第二種方案是使用 URL.createObjectURL(fileObj) 這個方法和canvas技術,  咱們先來看看 支持這個 URL.createObjectURL(fileObj) 的瀏覽器有哪些,咱們能夠點擊下面的鏈接查看:

http://caniuse.com/#search=createObjectURL/ 

 實現代碼以下:

function html5Reader(file) {         
    var fileObj = file.files[0],
        img = document.getElementById("img");   
        // URL.createObjectURL  safari不支持
    img.src = URL.createObjectURL(fileObj);
    img.onload =function() {
        var data = getBase64Image(img);
        console.log(data);  // 打印出base64編碼
    }
}
function getBase64Image(img) {
    var canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;

    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0, img.width, img.height);
    var ext = img.src.substring(img.src.lastIndexOf(".")+1).toLowerCase();
    var dataURL = canvas.toDataURL("image/"+ext);
    return dataURL;
}

HTML代碼以下:

<input type="file" id="logo" name="logo" accept="image/*">
<img src= '' id="img"/>
<div id="btn" style="margin-top:50px;font-size:40px;">btn</div>
<canvas id="myCanvas"></canvas>

全部的JS代碼以下:

<script>
        var EventUtil = {
            addHandler: function(element,type,handler) {
                if(element.addEventListener) {
                    element.addEventListener(type,handler,false);
                }else if(element.attachEvent) {
                    element.attachEvent("on"+type,handler);
                }else {
                    element["on" +type] = handler;
                }
            }
        };
         var btn = document.getElementById("btn");
         var pic = document.getElementById("img");
         function getBase64Image(img) {
              var canvas = document.createElement("canvas");
              canvas.width = img.width;
              canvas.height = img.height;

              var ctx = canvas.getContext("2d");
              ctx.drawImage(img, 0, 0, img.width, img.height);
              var ext = img.src.substring(img.src.lastIndexOf(".")+1).toLowerCase();
              var dataURL = canvas.toDataURL("image/"+ext);
              return dataURL;
         }
         var ua = navigator.userAgent.toLowerCase();
         EventUtil.addHandler(btn,'click',function(){
            var file = document.getElementById("logo");
            
            var ext=file.value.substring(file.value.lastIndexOf(".")+1).toLowerCase();
            
             // gif在IE瀏覽器暫時沒法顯示
             if(ext!='png'&&ext!='jpg'&&ext!='jpeg'){
                 alert("圖片的格式必須爲png或者jpg或者jpeg格式!"); 
                 return;
             }
             if(/msie ([^;]+)/.test(ua)) {
                  var lowIE10 = RegExp["$1"]*1;
                  if(lowIE10 == 6){
                        // IE6瀏覽器設置img的src爲本地路徑能夠直接顯示圖片
                        file.select();
                        // 在file控件下獲取焦點狀況下 document.selection.createRange() 將會拒絕訪問,因此咱們要失去下焦點。
                        file.blur();

                        var reallocalpath = document.selection.createRange().text;
                        pic.src = reallocalpath;
                  }else if(lowIE10 > 6 && lowIE10 < 10){
                      // IE7~9 IE10+按照html5的標準去處理
                      file.select();
                      // 在file控件下獲取焦點狀況下 document.selection.createRange() 將會拒絕訪問,因此咱們要失去下焦點。
                      file.blur();

                      var reallocalpath = document.selection.createRange().text;
                      // 非IE6版本的IE因爲安全問題直接設置img的src沒法顯示本地圖片,可是能夠經過濾鏡來實現
                      pic.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='image',src=\"" + reallocalpath + "\")";
                      // 設置img的src爲base64編碼的透明圖片 取消顯示瀏覽器默認圖片
                      pic.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==';
                  }else if(lowIE10 >= 10) {
                      html5Reader(file);
                  } 
             }else {
                html5Reader(file);
             }
         });
         
         function html5Reader(file) {
             var fileObj = file.files[0],
                img = document.getElementById("img");
              // URL.createObjectURL  safari不支持
              img.src = URL.createObjectURL(fileObj);
              img.onload =function() {
                  var data = getBase64Image(img);
                  console.log(data);  // 打印出base64編碼
              }
              /*
              var file = file.files[0];
              var reader = new FileReader();
              reader.readAsDataURL(file);
              reader.onload = function(e){
                 var pic = document.getElementById("img");
                 pic.src=this.result;
              }*/
         }
    </script>

上傳圖片demo下載

相關文章
相關標籤/搜索