关于javascript:在上传图像之前预览图像

Preview an image before it is uploaded

我想在上传文件(图像)之前预览它。预览操作应该在浏览器中全部执行,而不使用Ajax上传图像。

我该怎么做?


请看下面的示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function readURL(input) {

  if (input.files && input.files[0]) {
    var reader = new FileReader();

    reader.onload = function(e) {
      $('#blah').attr('src', e.target.result);
    }

    reader.readAsDataURL(input.files[0]);
  }
}

$("#imgInp").change(function() {
  readURL(this);
});
1
2
3
4
5
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
<form id="form1" runat="server">
  <input type='file' id="imgInp" />
  <img id="blah" src="#" alt="your image" />
</form>

另外,您可以在这里尝试这个示例。


有几种方法可以做到这一点。最有效的方法是从对文件使用url.createObjectURL()。将此URL传递给img.src,告诉浏览器加载提供的图像。

下面是一个例子:

1
2
3
4
5
6
7
<input type="file" accept="image/*" onchange="loadFile(event)">
<img id="output"/>

  var loadFile = function(event) {
    var output = document.getElementById('output');
    output.src = URL.createObjectURL(event.target.files[0]);
  };

您还可以使用filereader.readasdataurl()从解析文件。这将在内存中创建一个字符串,其中包含图像的base64表示。

1
2
3
4
5
6
7
8
9
10
11
<input type="file" accept="image/*" onchange="loadFile(event)">
<img id="output"/>

  var loadFile = function(event) {
    var reader = new FileReader();
    reader.onload = function(){
      var output = document.getElementById('output');
      output.src = reader.result;
    };
    reader.readAsDataURL(event.target.files[0]);
  };


一个线性解决方案:

以下代码使用对象URL,这比数据URL更有效地查看大图像(数据URL是包含所有文件数据的大字符串,而对象URL只是引用内存中文件数据的短字符串):

1
2
3
4
<img id="blah" alt="your image" width="100" height="100" />

<input type="file"
    onchange="document.getElementById('blah').src = window.URL.createObjectURL(this.files[0])">

生成的URL如下:

1
blob:http%3A//localhost/7514bc74-65d4-4cf0-a0df-3de016824345


Leasstatt的答案在FF和Chrome等"标准"浏览器中很好地工作。IE的解决方案存在,但看起来不同。下面介绍跨浏览器解决方案:

在HTML中,我们需要两个预览元素:img用于标准浏览器,div用于ie

HTML:

1
2
3
4
<img id="preview"
     src=""
     alt=""
     style="display:none; max-width: 160px; max-height: 120px; border: none;"/>

在CSS中,我们指定了以下特定于IE的内容:

CSS:

1
2
3
#preview_ie {
  FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale)
}

在HTML中,我们包括标准的和特定于IE的javascripts:

1
2
3
4
5
6
<script type="text/javascript">
  {% include"pic_preview.js" %}
 
<!--[if gte IE 7]>
<script type="text/javascript">
  {% include"pic_preview_ie.js" %}

pic_preview.js是leasstatt答案中的javascript。将$('#blah')替换为$('#preview')的位置,并添加$('#preview').show()

现在,特定于IE的javascript(pic_preview_ie.js):

1
2
3
4
5
6
function readURL (imgFile) {    
  var newPreview = document.getElementById('preview_ie');
  newPreview.filters.item('DXImageTransform.Microsoft.AlphaImageLoader').src = imgFile.value;
  newPreview.style.width = '160px';
  newPreview.style.height = '120px';
}

就是这样。适用于IE7、IE8、FF和Chrome。请在IE9中测试并报告。这里找到了IE预览的想法:http://forums.asp.net/t/1320559.aspx网站

http://msdn.microsoft.com/en-us/library/ms532969(v=vs.85).aspx


我已经编辑了@ivan的答案以显示"没有可用预览"图像,如果它不是图像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function readURL(input) {
    var url = input.value;
    var ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase();
    if (input.files && input.files[0]&& (ext =="gif" || ext =="png" || ext =="jpeg" || ext =="jpg")) {
        var reader = new FileReader();

        reader.onload = function (e) {
            $('.imagepreview').attr('src', e.target.result);
        }

        reader.readAsDataURL(input.files[0]);
    }else{
         $('.imagepreview').attr('src', '/assets/no_preview.png');
    }
}

这是一个多文件版本,基于IvanBaev的答案。

HTML

1
<input type="file" multiple id="gallery-photo-add">

javascript/jquery

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$(function() {
    // Multiple images preview in browser
    var imagesPreview = function(input, placeToInsertImagePreview) {

        if (input.files) {
            var filesAmount = input.files.length;

            for (i = 0; i < filesAmount; i++) {
                var reader = new FileReader();

                reader.onload = function(event) {
                    $($.parseHTML('<img>')).attr('src', event.target.result).appendTo(placeToInsertImagePreview);
                }

                reader.readAsDataURL(input.files[i]);
            }
        }

    };

    $('#gallery-photo-add').on('change', function() {
        imagesPreview(this, 'div.gallery');
    });
});

由于使用了$.ParseHTML,因此需要jQuery 1.8,这有助于缓解XSS。

这将是现成的,您唯一需要的依赖性是jquery。


对。这是可能的。

HTML

1
2
3
<input type="file" accept="image/*"  onchange="showMyImage(this)" />
 <br/>
<img id="thumbnil" style="width:20%; margin-top:10px;"  src="" alt="image"/>

JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 function showMyImage(fileInput) {
        var files = fileInput.files;
        for (var i = 0; i < files.length; i++) {          
            var file = files[i];
            var imageType = /image.*/;    
            if (!file.type.match(imageType)) {
                continue;
            }          
            var img=document.getElementById("thumbnil");            
            img.file = file;    
            var reader = new FileReader();
            reader.onload = (function(aImg) {
                return function(e) {
                    aImg.src = e.target.result;
                };
            })(img);
            reader.readAsDataURL(file);
        }    
    }

您可以从这里获得实时演示。


干净而简单杰西德

当您希望通过DIV或按钮间接触发事件时,这将非常有用。

1
2
3
4
5
6
7
8
9
10
11
12
13
<img id="image-preview"  style="height:100px; width:100px;"  src="">

<input style="display:none" id="input-image-hidden" onchange="document.getElementById('image-preview').src = window.URL.createObjectURL(this.files[0])" type="file" accept="image/jpeg, image/png">

<button  onclick="HandleBrowseClick('input-image-hidden');">UPLOAD IMAGE</button>


<script type="text/javascript">
function HandleBrowseClick(hidden_input_image)
{
    var fileinputElement = document.getElementById(hidden_input_image);
    fileinputElement.click();
}


使用javascript(jquery)和html5的多个图像示例

javascript(jquery)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function readURL(input) {
     for(var i =0; i< input.files.length; i++){
         if (input.files[i]) {
            var reader = new FileReader();

            reader.onload = function (e) {
               var img = $('<img id="dynamic">');
               img.attr('src', e.target.result);
               img.appendTo('#form1');  
            }
            reader.readAsDataURL(input.files[i]);
           }
        }
    }

    $("#imgUpload").change(function(){
        readURL(this);
    });
}

标记(HTML)

1
2
3
<form id="form1" runat="server">
    <input type="file" id="imgUpload" multiple/>
</form>

如何创建一个加载文件并触发自定义事件的函数?然后将监听器附加到输入。这样我们就可以更灵活地使用文件,而不仅仅是预览图像。

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
 * @param {domElement} input - The input element
 * @param {string} typeData - The type of data to be return in the event object.
 */

function loadFileFromInput(input,typeData) {
    var reader,
        fileLoadedEvent,
        files = input.files;

    if (files && files[0]) {
        reader = new FileReader();

        reader.onload = function (e) {
            fileLoadedEvent = new CustomEvent('fileLoaded',{
                detail:{
                    data:reader.result,
                    file:files[0]  
                },
                bubbles:true,
                cancelable:true
            });
            input.dispatchEvent(fileLoadedEvent);
        }
        switch(typeData) {
            case 'arraybuffer':
                reader.readAsArrayBuffer(files[0]);
                break;
            case 'dataurl':
                reader.readAsDataURL(files[0]);
                break;
            case 'binarystring':
                reader.readAsBinaryString(files[0]);
                break;
            case 'text':
                reader.readAsText(files[0]);
                break;
        }
    }
}
function fileHandler (e) {
    var data = e.detail.data,
        fileInfo = e.detail.file;

    img.src = data;
}
var input = document.getElementById('inputId'),
    img = document.getElementById('imgId');

input.onchange = function (e) {
    loadFileFromInput(e.target,'dataurl');
};

input.addEventListener('fileLoaded',fileHandler)

也许我的代码不如某些用户好,但我想你会明白的。这里你可以看到一个例子


以下是工作代码。

1
2
<input type='file' onchange="readURL(this);" />
<img id="ShowImage" src="#" />

Javascript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 function readURL(input) {
        if (input.files && input.files[0]) {
            var reader = new FileReader();

            reader.onload = function (e) {
                $('#ShowImage')
                    .attr('src', e.target.result)
                    .width(150)
                    .height(200);
            };

            reader.readAsDataURL(input.files[0]);
        }
    }


这个解决方案怎么样?

只需将数据属性"data type=editable"添加到图像标记中,如下所示:

1
<img data-type="editable" id="companyLogo" src="http://www.coventrywebgraphicdesign.co.uk/wp-content/uploads/logo-here.jpg" height="300px" width="300px" />

你项目的脚本偏离了程序…

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
function init() {
    $("img[data-type=editable]").each(function (i, e) {
        var _inputFile = $('<input/>')
            .attr('type', 'file')
            .attr('hidden', 'hidden')
            .attr('onchange', 'readImage()')
            .attr('data-image-placeholder', e.id);

        $(e.parentElement).append(_inputFile);

        $(e).on("click", _inputFile, triggerClick);
    });
}

function triggerClick(e) {
    e.data.click();
}

Element.prototype.readImage = function () {
    var _inputFile = this;
    if (_inputFile && _inputFile.files && _inputFile.files[0]) {
        var _fileReader = new FileReader();
        _fileReader.onload = function (e) {
            var _imagePlaceholder = _inputFile.attributes.getNamedItem("data-image-placeholder").value;
            var _img = $("#" + _imagePlaceholder);
            _img.attr("src", e.target.result);
        };
        _fileReader.readAsDataURL(_inputFile.files[0]);
    }
};

//
// IIFE - Immediately Invoked Function Expression
// https://stackoverflow.com/questions/18307078/jquery-best-practises-in-case-of-document-ready
(

function (yourcode) {
   "use strict";
    // The global jQuery object is passed as a parameter
    yourcode(window.jQuery, window, document);
}(

function ($, window, document) {
   "use strict";
    // The $ is now locally scoped
    $(function () {
        // The DOM is ready!
        init();
    });

    // The rest of your code goes here!
}));

见JSfiddle演示


试试这个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
window.onload = function() {
  if (window.File && window.FileList && window.FileReader) {
    var filesInput = document.getElementById("uploadImage");
    filesInput.addEventListener("change", function(event) {
      var files = event.target.files;
      var output = document.getElementById("result");
      for (var i = 0; i < files.length; i++) {
        var file = files[i];
        if (!file.type.match('image'))
          continue;
        var picReader = new FileReader();
        picReader.addEventListener("load", function(event) {
          var picFile = event.target;
          var div = document.createElement("div");
          div.innerHTML ="<img class='thumbnail' src='" + picFile.result +"'" +
           "title='" + picFile.name +"'/>";
          output.insertBefore(div, null);
        });        
        picReader.readAsDataURL(file);
      }

    });
  }
}
1
<input type="file" id="uploadImage" name="termek_file" class="file_input" multiple/>


对于多个图像上传(修改@ivanbaev的解决方案)

1
2
3
4
5
6
7
8
9
10
11
12
function readURL(input) {
    if (input.files && input.files[0]) {
        var i;
        for (i = 0; i < input.files.length; ++i) {
          var reader = new FileReader();
          reader.onload = function (e) {
              $('#form1').append('<img src="'+e.target.result+'">');
          }
          reader.readAsDataURL(input.files[i]);
        }
    }
}

http://jsfiddle.net/lvsyc/12330/

希望这能帮助别人。


我已经做了一个插件,它可以在IE 7+中生成预览效果,这要归功于互联网,但没有什么限制。我把它放进一个Github页面,这样更容易得到它

1
2
3
4
5
6
7
8
9
10
11
12
$(function () {
        $("input[name=file1]").previewimage({
            div:".preview",
            imgwidth: 180,
            imgheight: 120
        });
        $("input[name=file2]").previewimage({
            div:".preview2",
            imgwidth: 90,
            imgheight: 90
        });
    });
1
2
3
4
5
6
7
8
9
.preview > div {
  display: inline-block;
  text-align:center;
}

.preview2 > div {
  display: inline-block;
  text-align:center;
}
1
2
3
4
5
6
7
8
9
10
11
12
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
<script src="https://rawgit.com/andrewng330/PreviewImage/master/preview.image.min.js">
    Preview
   
    Preview2
   

    <form action="#" method="POST" enctype="multipart/form-data">
        <input type="file" name="file1">
        <input type="file" name="file2">
        <input type="submit">
    </form>


这是我的代码。支持IE[6-9]、Chrome 17+、Firefox、Opera 11+、MaxThon3

HTML

1
2
<input type="file"  id="netBarBig"  onchange="changeFile(this)"  />
<img  src="" id="imagePreview" style="width:120px;height:80px;" alt=""/>

JavaScript:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
function previewImage(fileObj, imgPreviewId) {
    var allowExtention =".jpg,.bmp,.gif,.png";  //allowed to upload file type
    document.getElementById("hfAllowPicSuffix").value;
    var extention = fileObj.value.substring(fileObj.value.lastIndexOf(".") + 1).toLowerCase();
    var browserVersion = window.navigator.userAgent.toUpperCase();
    if (allowExtention.indexOf(extention) > -1) {
        if (fileObj.files) {
            if (window.FileReader) {
                var reader = new FileReader();
                reader.onload = function (e) {
                    document.getElementById(imgPreviewId).setAttribute("src", e.target.result);
                };
                reader.readAsDataURL(fileObj.files[0]);
            } else if (browserVersion.indexOf("SAFARI") > -1) {
                alert("don't support  Safari6.0 below broswer");
            }
        } else if (browserVersion.indexOf("MSIE") > -1) {
            if (browserVersion.indexOf("MSIE 6") > -1) {//ie6
                document.getElementById(imgPreviewId).setAttribute("src", fileObj.value);
            } else {//ie[7-9]
                fileObj.select();
                fileObj.blur();
                var newPreview = document.getElementById(imgPreviewId);

                newPreview.style.border ="solid 1px #eeeeee";
                newPreview.style.filter ="progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='" + document.selection.createRange().text +"')";
                newPreview.style.display ="block";

            }
        } else if (browserVersion.indexOf("FIREFOX") > -1) {//firefox
            var firefoxVersion = parseFloat(browserVersion.toLowerCase().match(/firefox\/([\d.]+)/)[1]);
            if (firefoxVersion < 7) {//firefox7 below
                document.getElementById(imgPreviewId).setAttribute("src", fileObj.files[0].getAsDataURL());
            } else {//firefox7.0+&nbsp;
                document.getElementById(imgPreviewId).setAttribute("src", window.URL.createObjectURL(fileObj.files[0]));
            }
        } else {
            document.getElementById(imgPreviewId).setAttribute("src", fileObj.value);
        }
    } else {
        alert("only support" + allowExtention +"suffix");
        fileObj.value =""; //clear Selected file
        if (browserVersion.indexOf("MSIE") > -1) {
            fileObj.select();
            document.selection.clear();
        }

    }
}
function changeFile(elem) {
    //file object , preview img tag id
    previewImage(elem,'imagePreview')
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function assignFilePreviews() {
    $('input[data-previewable="true"]').change(function() {
        var prvCnt = $(this).attr('data-preview-container');
        if (prvCnt) {
            if (this.files && this.files[0]) {
                var reader = new FileReader();
                reader.onload = function(e) {
                    var img = $('<img>');
                    img.attr('src', e.target.result);
                    img.error(function() {
                        $(prvCnt).html('');
                    });
                    $(prvCnt).html('');
                    img.appendTo(prvCnt);
                }
                reader.readAsDataURL(this.files[0]);
            }
        }
    });
}
$(document).ready(function() {
    assignFilePreviews();
});

HTML

1
<input type="file" data-previewable="true" data-preview-container=".prd-img-prv" />

当选择了无效类型(例如pdf)的文件时,也会处理这种情况。


对于我的应用程序,加上加密的get-url参数,只有这样才有效。我总是得到一个TypeError: $(...) is null。摘自https://developer.mozilla.org/en-us/docs/web/api/filereader/readasdataurl

1
2
3
4
5
6
7
8
9
10
11
12
13
function previewFile() {
  var preview = document.querySelector('img');
  var file    = document.querySelector('input[type=file]').files[0];
  var reader  = new FileReader();

  reader.addEventListener("load", function () {
    preview.src = reader.result;
  }, false);

  if (file) {
    reader.readAsDataURL(file);
  }
}
1
2
<input type="file" onchange="previewFile()">
<img src="" height="200" alt="Image preview...">