javascript和HTML5上传图片之前实现预览效果

一:FileList对象与file对象

FileList对象表示用户选择的文件列表,在HTML4中,file控件内只允许放置一个文件,但是到了HTML5中,通过添加multiple属性,file控件内允许一次放置多个文件,控件内的每一个用户选择的文件都是一个file对象,而FileList对象是file对象的列表;

比如如下代码:

选择文件<input type="file" id="file" multiple size="80"/>
<input type="button" onclick="ShowFileName();" value="文件上传"/>

我们可以按住ctrl键选择多个文件;

JS代码如下:

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属性等;

二: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+‘" />‘;
        }
    }
    // 将文件以二进制形式读入页面
    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下载

时间: 2024-09-30 06:14:42

javascript和HTML5上传图片之前实现预览效果的相关文章

HTML5 CSS3 经典案例:无插件拖拽上传图片 (支持预览与批量) (二)

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/31513065 上一篇已经实现了这个项目的整体的HTML和CSS: HTML5 CSS3 经典案例:无插件拖拽上传图片 (支持预览与批量) (一) 这篇博客直接在上篇的基础上完成,最终效果: 效果图1: 效果图2: 好了,请允许我把图片贴了两遍,方便大家看效果了~ 可以看出我们的图片的li的html其实还是挺复杂的,于是我把html文档做了一些修改: <span style=&quo

html5+js实现图片预览

在上传图片时,经常需要预览图片. 本用例使用html5+js实现上传图片的本地预览.鼠标移至预览图片可以显示大图. 代码: <html> <head> <title>My JSP '01.jsp' starting page</title> <link rel="stylesheet" type="text/css" href="css/common.css" /> <script

前端实现input[type=&#39;file&#39;]上传图片预览效果

众所周知JavaScript在设计上处于安全角度考虑,是不允许读写本地文件的(原因请自行百度): 但是在实际项目应用中,经常会使用到上传图片,并且可以让用户直接预览图片.对于此种做法有两种方法可以实现:一是前后台交互,后台将图片地址返回前端: 二是,我今天写的内容,使用FileReader对象--允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容:此种方法可以优化图片加载速度,减少方法一占用带宽的问题: 但是,此种方法兼容性存在问题,主要是IE浏览器(ie10以上没问题

jquery实现上传图片及图片大小验证、图片预览效果代码

jquery实现上传图片及图片大小验证.图片预览效果代码 上传图片验证 */ function submit_upload_picture(){     var file = $('file_c').value;     if(!/.(gif|jpg|jpeg|png|gif|jpg|png)$/.test(file)){            alert("图片类型必须是.gif,jpeg,jpg,png中的一种")        }else{      $('both_form')

JavaScript 图片上传预览效果

图片上传预览是一种在图片上传之前对图片进行本地预览的技术.使用户选择图片后能立即查看图片,而不需上传服务器,提高用户体验.但随着浏览器安全性的提高,要实现图片上传预览也越来越困难.不过群众的智慧是无限的,网上已经有很多变通或先进的方法来实现.例如ie7/ie8的滤镜预览法,firefox 3的getAsDataURL方法.但在opera.safari和chrome还是没有办法实现本地预览,只能通过后台来支持预览.在研究了各种预览方法后,作为总结,写了这个程序,跟大家一起分享.上次写的简便无刷新文

JS实现图片上传预览效果:方法一

<script type="text/javascript"> //处理file input加载的图片文件 $(document).ready(function(e) { //判断浏览器是否有FileReader接口 if(typeof FileReader =='undefined') { /*$("#images_show").css({'background':'none'}).html('亲,您的浏览器还不支持HTML5的FileReader接口

JS兼容各个浏览器的本地图片上传即时预览效果

很早以前 在杭州银行工作曾经碰到这么一个需求,当时也是纠结了很久,也是google了很久,没有碰到合适的demo,今天特意研究了下这方面的的问题,所以也就做了个简单的demo来实现 本地上传图片即时预览效果.其在标准浏览器(firefox,chrome,IE10等其他浏览器)用了HTML5中的内容实现图片即时预览效果.在IE10以下浏览器用了滤镜来解决图片显示问题.在看代码之前,先让我们来了解以下知识点: HTML5中的FileReader对象: FileReader对象主要是把文件读入内存中,

图片上传即时预览效果

做项目时一同事推荐的一个picload插件,实现图片上传后,即时预览效果,感觉很不错,分享出来. 点击上传图片后.立即看到预览的效果如下图: 布局代码: <div class="banner" id="CoupicPicYes">图片预览</div> <a class="input-file" href="javascript:void(0);" onclick="$('#photoUp

带预览效果的幻灯片

正在做一个带预览效果的幻灯片. 首先,要分析整个效果.采用VCD分析法(V;view; C: contral; D:data). 先观察整个效果图,将效果图划分为不同的块级.画出结构分析图,设置每个大块的类名. 分析要使用的数据. 进行代码开发:1, 视觉效果开发: HTML + CSS; 2, 动画效果: javascript; HTML页面编写,先架好结构,并用css样式来使页面变成要展示的样子.(以前总是看着图,事无巨细的一层层写下来,并一小块一小块的去做好样式设置,发现这样不仅浪费时间,