在上传图像之前预览图像

Sim*_*ian 1476 javascript jquery file-upload

我希望能够在上传之前预览文件(图像).预览操作应该在浏览器中全部执行,而不使用Ajax上传图像.

我怎样才能做到这一点?

小智 2379

请看下面的示例代码:

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);
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form runat="server">
  <input type='file' id="imgInp" />
  <img id="blah" src="#" alt="your image" />
</form>
Run Code Online (Sandbox Code Playgroud)

此外,您可以在此处尝试此示例.

  • 为什么将jQuery用于`$('#blah').attr('src',e.target.result);`什么时候你可以简单地完成`document.getElementById('blah').src = e.target.result )` (63认同)
  • 您可以通过定义一次读取器来提高性能.http://jsfiddle.net/LvsYc/638/ (4认同)
  • 我做了[ReactJS的实现](http://codepen.io/sumi1985/pen/bqRpQM).奇迹般有效.@kxc你应该进行ajax调用并发送`input.files [0]`作为数据,[参见jQuery的doc](http://api.jquery.com/jquery.ajax/). (4认同)
  • 为什么不使用`reader.result`而不是`e.target.result`? (3认同)

nkr*_*ron 311

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

这是一个例子:

<input type="file" accept="image/*" onchange="loadFile(event)">
<img id="output"/>
<script>
  var loadFile = function(event) {
    var output = document.getElementById('output');
    output.src = URL.createObjectURL(event.target.files[0]);
  };
</script>
Run Code Online (Sandbox Code Playgroud)

您还可以使用FileReader.readAsDataURL()来解析<input>中的文件.这将在内存中创建一个包含图像的base64表示的字符串.

<input type="file" accept="image/*" onchange="loadFile(event)">
<img id="output"/>
<script>
  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]);
  };
</script>
Run Code Online (Sandbox Code Playgroud)

  • 仔细阅读:readAsDataURL和createObjectURL将在浏览器中缓存一个图像,然后返回一个base64编码的字符串,该字符串引用缓存中的图像位置.如果清除浏览器缓存,则base64编码的字符串将不再引用该图像.base64字符串不是实际的图像数据,它是对图像的url引用,您不应将其保存到希望检索图像数据的数据库中.我最近犯了这个错误(约3分钟前). (32认同)
  • 为了避免内存问题,当您完成Blob处理后,应该调用`URL.revokeObjectURL`。 (5认同)
  • @Apolo 不在这种情况下,请参阅此答案:/sf/answers/3454263011/ (4认同)
  • 仔细阅读:当使用文件输入上传图像时,它将存储在浏览器的缓存中。`URL.createObjectURL()` 将创建一个指向浏览器上缓存图像的链接。要创建可存储在数据库中的文件的 base64 字符串,请使用“readAsDataURL”。 (2认同)

cnl*_*evy 191

单线解决方案:

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

<img id="blah" alt="your image" width="100" height="100" />

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

生成的URL将如下:

blob:http%3A//localhost/7514bc74-65d4-4cf0-a0df-3de016824345
Run Code Online (Sandbox Code Playgroud)

  • **版本通知**:IE10 + http://caniuse.com/#feat=bloburls支持 (4认同)
  • @Raptor也是整个File API ...(`FileReader`,`input.files`等)。URL.createObjectURL`是处理用户提交的文件时的一种方式,它仅创建一个内存中的符号链接到用户磁盘上的真实文件。 (2认同)
  • 美丽的。但是使用 URL.revokeObjectURL() 清除内存怎么样?:D (2认同)

Mer*_*n K 46

这是最简单的方法


在不使用 Ajax 或任何复杂功能的情况下从浏览器将图像上传到服务器之前预览图像。


它需要一个“ onChange ”事件来加载图像。

function preview() {
    frame.src=URL.createObjectURL(event.target.files[0]);
}
Run Code Online (Sandbox Code Playgroud)
<form>
  <input type="file" onchange="preview()">
  <img id="frame" src="" width="100px" height="100px"/>
</form>
Run Code Online (Sandbox Code Playgroud)

要预览多张图片,请单击此处

  • 重要提示:如果/当使用此方法时,有必要删除对象 URL 以防止内存泄漏。这是通过调用“URL.revokeObjectURL(myObjectUrl)”来完成的,其中“myObjectUrl”是创建的对象 URL(这意味着您需要在设置图像 src 之前将对象 URL 分配给临时变量)。请参阅 https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL#memory_management。 (3认同)

小智 45

LeassTaTT的答案在FF和Chrome等"标准"浏览器中运行良好.IE的解决方案存在,但看起来不同.这里描述跨浏览器解决方案:

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

HTML:

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

<div id="preview_ie"></div>
Run Code Online (Sandbox Code Playgroud)

在CSS中我们指定以下IE特定的东西:

CSS:

#preview_ie {
  FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale)
}  
Run Code Online (Sandbox Code Playgroud)

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

<script type="text/javascript">
  {% include "pic_preview.js" %}
</script>  
<!--[if gte IE 7]> 
<script type="text/javascript">
  {% include "pic_preview_ie.js" %}
</script>
Run Code Online (Sandbox Code Playgroud)

pic_preview.js是来自LeassTaTT答案的Javascript.更换 $('#blah')蒙山的$('#preview'),并添加$('#preview').show()

现在IE特定的Javascript(pic_preview_ie.js):

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';
}    
Run Code Online (Sandbox Code Playgroud)

那是.适用于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


Sac*_*sad 23

我编辑了@ Ivan的答案,显示"No Preview Available"图像,如果它不是图像:

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');
    }
}
Run Code Online (Sandbox Code Playgroud)


Nin*_*pac 17

这是一个多文件版本,基于Ivan Baev的回答.

HTML

<input type="file" multiple id="gallery-photo-add">
<div class="gallery"></div>
Run Code Online (Sandbox Code Playgroud)

JavaScript/jQuery

$(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');
    });
});
Run Code Online (Sandbox Code Playgroud)

由于使用$ .parseHTML,需要jQuery 1.8,这应该有助于XSS缓解.

这将是开箱即用的,你需要的唯一依赖是jQuery.


小智 15

是.有可能的.

HTML

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

JS

 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);
        }    
    }
Run Code Online (Sandbox Code Playgroud)

你可以从这里获得现场演示.


Kam*_*ski 14

这是cmlevy 答案的尺寸改进- 尝试

<input type=file oninput="pic.src=window.URL.createObjectURL(this.files[0])">
<img id="pic" />
Run Code Online (Sandbox Code Playgroud)

  • @Bbb它看起来不像典型的路径 - 它看起来像一些临时“链接”:`blob:null / 35c35011-111c-4d9e-ac3f-a779e049eb3d` (2认同)

Mer*_*n K 12

使用 jquery预览多个文件

$(document).ready(function(){
    $('#image').change(function(){
        $("#frames").html('');
        for (var i = 0; i < $(this)[0].files.length; i++) {
            $("#frames").append('<img src="'+window.URL.createObjectURL(this.files[i])+'" width="100px" height="100px"/>');
        }
    });
});
Run Code Online (Sandbox Code Playgroud)
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
    <input type="file" id="image" name="image[]" multiple /><br/>
    <div id="frames"></div>
</body>
Run Code Online (Sandbox Code Playgroud)


Siv*_*nan 10

干净简洁的 JSfiddle

当您希望从div或按钮间接触发事件时,这将非常有用.

<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();
}     
</script>
Run Code Online (Sandbox Code Playgroud)


Rat*_*aul 7

使用JavaScript(jQuery)和HTML5的多个图像的示例

JavaScript(jQuery)

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);
    });
}
Run Code Online (Sandbox Code Playgroud)

标记(HTML)

<form id="form1" runat="server">
    <input type="file" id="imgUpload" multiple/>
</form>
Run Code Online (Sandbox Code Playgroud)


Mel*_*lle 7

在 React 中,如果文件在你的 props 中,你可以使用:

{props.value instanceof File && (
    <img src={URL.createObjectURL(props.value)}/>
)}
Run Code Online (Sandbox Code Playgroud)


ajo*_*era 5

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

/**
 * @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)
Run Code Online (Sandbox Code Playgroud)

可能我的代码不如某些用户好,但我认为你会明白这一点.在这里你可以看到一个例子


Muh*_*ais 5

以下是工作代码。

<input type='file' onchange="readURL(this);" /> 
<img id="ShowImage" src="#" />
Run Code Online (Sandbox Code Playgroud)

Javascript:

 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]);
        }
    }
Run Code Online (Sandbox Code Playgroud)