FileReader上传文件即使显示(但不负责持久化, 只是内存中的回显处理)

FileReader对象的readAsDataURL方法可以将读取到的文件编码成Data URL。Data URL是一项特殊的技术,可以将资料(例如图片)内嵌在网页之中,不用放到外部文件。使用Data URL的好处是,您不需要额外再发出一个HTTP 请求到服务器端取得额外的资料;而缺点便是,网页的大小可能会变大。它适合应用在内嵌小图片,不建议将大图像文件编码成Data URL来使用。您的图像文件不能够超过浏览器限定的大小,否则无法读取图像文件。

参考以下使用readAsDataURL读取图像文件范例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml" >
<head>
     <title> </title>
     <script type = "text/javascript" >
         function ProcessFile( e ) {
             var file = document.getElementById( 'file' ).files[ 0 ];
             if (file) {
                
                 var reader = new FileReader();
                 reader.onload = function ( event ) {
                     var txt = event.target.result;
                     document.getElementById( "result" ).innerHTML = txt;
                     };
               }
             reader.readAsDataURL( file );
             }
         function contentLoaded () {
             document.getElementById( 'file' ).addEventListener( 'change' ,
ProcessFile , false );
         }
         window.addEventListener( "DOMContentLoaded" , contentLoaded , false );
     </script>
</head>
<body>
    请选取一个图像文件: <input type = "file" id = "file" name = "file" />
    <div id = "result" > </div>
</body>
</html>

 

readAsDataURL方法会使用base-64进行编码,编码的资料由data字串开始,后面跟随的是MIME type,然后再加上base64字串,逗号之后就是编码过的图像文件的内容。

使用Img显示图像文件

 

若想要将读取出来的图像文件,直接显示在网页上,您可以透过JavaScript建立一个<img>标签,再设定src属性为Data URL,再将<img>标签加入DOM之中,例如以下范例所示:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml" >
<head>
<title> </title>
<script type = "text/javascript" >
function ProcessFile( e ) {
var file = document.getElementById( 'file' ).files[ 0 ];
if ( file ) {
 
var reader = new FileReader();
reader.onload = function ( event ) {
var txt = event.target.result;
var img = document.createElement( "img" );
img.src = txt;
document.getElementById( "result" ).appendChild( img );
};
}
reader.readAsDataURL( file );
}
function contentLoaded() {
document.getElementById( 'file' ).addEventListener( 'change' ,
ProcessFile , false );
}
window.addEventListener( "DOMContentLoaded" , contentLoaded , false );
</script>
</head>
<body>
请选取一个图像文件: <input type = "file" id = "file" name = "file" />
<div id = "result" > </div>
</body>
</html>

读取部分文件

有时想要读取的文件太大,想要分段进行读取;或者只想要读取文件部分的内容,这时您可以将文件切割,根据浏览器的不同,可以使用以下方法:

webkitSlice:适用于支持Webkit引擎的浏览器,如Chrome。
mozSlice:适用于Firefox。

这两个方法要传入开始的位元组索引,以及结尾的位元组索引,索引以0开始。以下程式范例以FileReader对象的readAsBinaryString方法来读取文件,只读取文件的第三个位元组读取到第六个位元组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml" >
<head>
<title> </title>
<script type = "text/javascript" >
function ProcessFile( e ) {
var file = document.getElementById( 'file' ).files[ 0 ];
if ( file ) {
var reader = new FileReader ();
reader.onload = function ( event ) {
var txt = event.target.result;
document.getElementById( "result" ).innerHTML = txt;
};
}
if ( file.webkitSlice ) {
var blob = file.webkitSlice( 2 , 4 );
} else if ( file.mozSlice ) {
var blob = file.mozSlice( 2 , 4 );
}
reader.readAsBinaryString( blob );
}
function contentLoaded() {
document.getElementById( 'file' ).addEventListener( 'change' ,
ProcessFile , false );
}
window.addEventListener( "DOMContentLoaded" , contentLoaded , false );
</script>
</head>
<body>
<input type = "file" id = "file" name = "file" />
<div id = "result" > </div>
</body>
</html>


请注意:
不同的浏览器对于HTML 5的支持程度不同,上述程式码可在chrome正常执行,不见得可以在其它浏览器中正确的执行。



实例:

new.html.erb中:

 <%= form_for [:activity, @angle], html: { multipart: true } do |f| %>
    <div class="upload-body">
      <div id="angle-photo" οnclick="fileUpload.click()" class="upload-photo" style="background-image: url(http://cdn.a0.bnbtrip.com/assets/images/mobile/2016/06/03/btn_Upload%20photos.jpg)">
        <input id="fileUpload" capture="camera" class="upload-angle-photo" type="file" name="angle[photo]">
      </div>


angle.js中:

  $("#fileUpload").on('change', function () {
    if (typeof (FileReader) != "undefined") {
      var reader = new FileReader();
      var Orientation = null;
      reader.onload = function (e) {
        var exif = EXIF.readFromBinaryFile(new BinaryFile(e.target.result));
        Orientation = exif.Orientation;
        var image = new Image();
        image.src = e.target.result;
        image.onload = function () {
          var expectWidth = this.naturalWidth;
          var expectHeight = this.naturalHeight;
          if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) {
            expectWidth = 800;
            expectHeight = expectWidth * this.naturalHeight / this.naturalWidth;
          } else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) {
            expectHeight = 1200;
            expectWidth = expectHeight * this.naturalWidth / this.naturalHeight;
          };
          var canvas = document.createElement("canvas");
          var ctx = canvas.getContext("2d");
          canvas.width = expectWidth;
          canvas.height = expectHeight;
          ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
          var base64 = null;
          if (navigator.userAgent.match(/iphone/i)) {
            console.log('iphone');
            if(Orientation != "" && Orientation != 1){
              switch(Orientation){
                case 6://需要顺时针(向左)90度旋转
                  //alert('需要顺时针(向左)90度旋转');
                  rotateImg(this,'left',canvas);
                  break;
                case 8://需要逆时针(向右)90度旋转
                  //alert('需要顺时针(向右)90度旋转');
                  rotateImg(this,'right',canvas);
                  break;
                case 3://需要180度旋转
                  //alert('需要180度旋转');
                  rotateImg(this,'right',canvas);//转两次
                  rotateImg(this,'right',canvas);
                  break;
              }
            }
            base64 = canvas.toDataURL("image/jpeg", 0.8);
          //}else if (navigator.userAgent.match(/Android/i)) {// 修复android
          //  var encoder = new JPEGEncoder();
          //  base64 = encoder.encode(ctx.getImageData(0, 0, expectWidth, expectHeight), 80);
          }else{
            if(Orientation != "" && Orientation != 1){
              //alert('旋转处理');
              switch(Orientation){
                case 6://需要顺时针(向左)90度旋转
                  //alert('需要顺时针(向左)90度旋转');
                  rotateImg(this,'left',canvas);
                  break;
                case 8://需要逆时针(向右)90度旋转
                  //alert('需要顺时针(向右)90度旋转');
                  rotateImg(this,'right',canvas);
                  break;
                case 3://需要180度旋转
                  //alert('需要180度旋转');
                  rotateImg(this,'right',canvas);//转两次
                  rotateImg(this,'right',canvas);
                  break;
              }
            }
            base64 = canvas.toDataURL("image/jpeg", 0.8);
          }
          $("#angle-photo").attr("style", "background-image: url("+base64+")");
        }
      };
      reader.onloadend = function (e) {
        var exif = EXIF.readFromBinaryFile(new BinaryFile(e.target.result));
        switch(exif.Orientation){
          case 8:
            ctx.rotate(90*Math.PI/180);
            break;
          case 3:
            ctx.rotate(180*Math.PI/180);
            break;
          case 6:
            ctx.rotate(-90*Math.PI/180);
            break;
        }
      }
      reader.readAsDataURL($(this)[0].files[0]);
    } else {
      console.log("This browser does not support FileReader.");
    }
  });


angles_controller.rb中:


  def create

    @angle = Angle.new(angle_params)
    if @angle.save
      redirect_to activity_angle_path(@angle)
    else
      flash[:error] = "请求参数错误!"
      redirect_to action: 'new'
    end
  end


  private
    def angle_params
      params.require(:angle).permit(:nickname, :photo, :gender, :about, :phone)
    end



也就是说filereader中reader.readAsDataURL($(this)[0].files[0]);所得到的url在reader.onload(e)函数中用e.target.result来表示从而进行DOM的替换, 而readAsDataURL函数相当与把图片加载到内存进行处理得到url进行回显的过程, 不存在异步存储持久化的过程,持久化是在进行表单提交的时候健壮参数中包含的photo来存入数据库的, 也就是和FileUpload(jquery插件)的功能完全不同, FileUpload是做文件的异步ajax, FileReader是做暂时的回显


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值