Câu hỏi Xem trước hình ảnh trước khi được tải lên


Tôi muốn có thể xem trước một tập tin (hình ảnh) trước khi nó được tải lên. Hành động xem trước sẽ được thực hiện tất cả trong trình duyệt mà không cần sử dụng Ajax để tải lên hình ảnh.

Tôi có thể làm cái này như thế nào?


1180
2017-12-16 09:51


gốc


Lưu ý rằng trừ khi bạn sử dụng Gears hoặc plugin khác, bạn không thể thao tác hình ảnh bên trong trình duyệt: code.google.com/p/chromium/issues/detail?id=32276 - Steve-o
Kiểm tra cách tiếp cận JavaScript thuần túy này, bao gồm câu trả lời của nó và nhận xét của Ray Nicholus về giải pháp cuối cùng: stackoverflow.com/questions/16430016/… - Jonathan Root
Đây là một bài viết chi tiết tuyệt vời với bản trình diễn trực tiếp codepedia.info/2015/06/… - Satinder singh
Đây là một giải pháp đơn giản không sử dụng jquery: developer.mozilla.org/en-US/docs/Web/API/FileReader/… - John Gilmer
angulartutorial.net/2017/02/… - Prashobh


Các câu trả lời:


Vui lòng xem mã mẫu bên dưới:

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

Bạn cũng có thể thử mẫu này ở đây.


1943
2017-12-16 09:55



các công trình trên trong Fx 3.6 và Chrome trên XP của tôi. - mplungjan
Cảm ơn ... bạn là một người tiết kiệm cuộc sống: D Giải pháp của bạn là người duy nhất làm việc và tin tôi khi tôi nói rằng tôi đã tìm kiếm rất nhiều trên Internet cho thủ thuật này. Trên gmail (soạn thư -> chèn hình ảnh), chúng hiển thị cho bạn bản xem trước nhưng hình ảnh được tải lên máy chủ của họ trước tiên và sau đó được hiển thị trong trình duyệt của bạn. - Igor Popov
cảm ơn ... không làm việc trong IE 8 bất kỳ giải pháp ?? - abhijit
FileReader API chỉ được hỗ trợ trong IE10 trở lên. caniuse.com/filereader - Kelly Cook
Tại sao lại sử dụng jQuery cho `$ ('# blah'). Attr ('src', e.target.result);` khi bạn có thể thực hiện đơn giản document.getElementById('blah').src=e.target.result) - EasyBB


Có một vài cách bạn có thể làm điều này. Cách hiệu quả nhất sẽ là sử dụng URL.createObjectURL () trên Tập tin từ của bạn <input>. Chuyển URL này tới img.src để yêu cầu trình duyệt tải hình ảnh được cung cấp.

Đây là một ví dụ:

<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>

Bạn cũng có thể dùng FileReader.readAsDataURL () để phân tích cú pháp tệp từ <input> của bạn. Điều này sẽ tạo ra một chuỗi trong bộ nhớ có chứa một đại diện base64 của hình ảnh.

<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>


234
2017-11-27 08:17



Đọc kỹ: readAsDataURL và createObjectURL sẽ lưu một hình ảnh trong trình duyệt, sau đó trả lại chuỗi được mã hóa base64 tham chiếu đến vị trí hình ảnh trong bộ nhớ cache. Nếu bộ nhớ cache của trình duyệt bị xóa, chuỗi được mã hóa base64 sẽ không còn tham chiếu đến hình ảnh nữa. Chuỗi base64 không phải là dữ liệu hình ảnh thực tế, đó là tham chiếu url cho hình ảnh và bạn không nên lưu nó vào cơ sở dữ liệu với hy vọng sẽ lấy dữ liệu hình ảnh. Gần đây tôi đã mắc lỗi này (khoảng 3 phút trước). - tfmontague
@nkron Cảm ơn bạn đã trả lời. Tuy nhiên, hình ảnh biến mất khi khung nhìn quay trở lại từ bộ điều khiển sau khi gửi nó (trong MVC). Có thể giữ hình ảnh được chọn ngay cả khi kịch bản này không? - Clint Eastwood
@ H.Johnson, Hãy xem sessionStorage. Bạn có thể lưu phiên bản dataURL của hình ảnh vào sessionStorage và sau đó khôi phục lại nó khi quay lại trang. - nkron
Sử dụng giải pháp đầu tiên của (2) dựa trên thông số kỹ thuật của trình duyệt. - Rob Scott
Câu trả lời chính xác. Tôi có câu hỏi bổ sung về mã mẫu này: Tôi có thể thu hồi sau bằng cách nào? URL.revokeObjectURL () để giải phóng bộ nhớ, bởi vì sau nhiều lần kiểm tra, nó biến rất chậm. Cảm ơn trước. - RaRdEvA


Giải pháp một lớp:

Đoạn mã sau sử dụng URL đối tượng, hiệu quả hơn URL dữ liệu để xem hình ảnh lớn (URL dữ liệu là một chuỗi lớn chứa tất cả dữ liệu tệp, trong khi URL đối tượng, chỉ là một chuỗi ngắn tham chiếu đến dữ liệu tệp trong- ký ức):

<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 được tạo sẽ giống như sau:

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

128
2017-11-18 20:00



thông báo phiên bản: hỗ trợ bởi IE10 + caniuse.com/#feat=bloburls - Raptor
Đầu trang: nó chỉ hoạt động, nhanh như chớp, không phụ thuộc vào jquery, và nó là một lớp lót thực sự. Nếu bạn sử dụng jquery $('your_selector').attr('src', window.URL.createObjectURL(this.files[0])). Không đau. Cảm ơn bạn. - Cyril Duchon-Doris
@Raptor và như vậy là toàn bộ API tệp ... (FileReader, input.files v.v.) URL.createObjectURL là cách để đi khi xử lý các tệp do người dùng gửi, nó chỉ tạo liên kết tượng trưng trong bộ nhớ tới tệp thực trên đĩa của người dùng. - Kaiido
Có cách nào để sử dụng điều này với nhiều hình ảnh không? - Rich
@Giàu có: this.files[0] là hình ảnh đầu tiên ("0 th"). Chỉ cần lặp lại this.files và bạn có thể sử dụng nhiều hình ảnh để xem trước chúng. - Jesper


Câu trả lời của LeassTaTT hoạt động tốt trong các trình duyệt "chuẩn" như FF và Chrome. Giải pháp cho IE tồn tại, nhưng có vẻ khác nhau. Dưới đây là mô tả giải pháp trình duyệt chéo:

Trong HTML, chúng ta cần hai phần tử xem trước, img cho các trình duyệt chuẩn và div cho IE

HTML:

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

<div id="preview_ie"></div>

Trong CSS, chúng tôi chỉ định điều cụ thể của IE sau đây:

CSS:

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

Trong HTML, chúng tôi bao gồm Javascripts chuẩn và IE cụ thể:

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

Các pic_preview.js là Javascript từ câu trả lời của LeassTaTT. Thay thế cái $('#blah') whith the $('#preview') và thêm $('#preview').show()

Bây giờ Javascript cụ thể của IE (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';
}    

Đó là. Hoạt động trong IE7, IE8, FF và Chrome. Vui lòng kiểm tra trong IE9 và báo cáo. Ý tưởng về bản xem trước của IE được tìm thấy ở đây: http://forums.asp.net/t/1320559.aspx

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


41
2017-12-24 11:58



Không hoạt động trong IE8 + vì đường dẫn được trả về thông qua "imgFile.value" trong javascript của bạn là không thực. Bắt đầu từ IE8, MS đã thêm một tính năng bảo mật nơi không thể truy cập đường dẫn thực trên hệ thống tệp. (cách duy nhất xung quanh đó là để trang web được thêm vào các trang web đáng tin cậy) - Jeff
Chỉ cần thử nghiệm trên IE 7, 8, 9: hoạt động TUYỆT VỜI! Đây là phép thuật, u một anh hùng của tôi :) Thx! Không biết tại sao, nhưng thuộc tính lọc kiểu dáng để div trực tiếp (style = "filter: ...") làm cho nó hoạt động!
xin vui lòng làm thế nào để làm nếu tôi muốn hoàn tác nó, có ví dụ một tùy chọn "hủy bỏ" để hủy bỏ xem trước hình ảnh - medBo
không, nó không hoạt động trong IE .. - Raheel Hasan
Trường hợp của tôi: nó hoạt động trên IE 7, 8 và 9, nhưng không hoạt động cho IE10 - Justin


Tôi đã chỉnh sửa câu trả lời của @ Ivan để hiển thị hình ảnh "Không có bản xem trước", nếu đó không phải là hình ảnh:

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');
    }
}

22
2018-06-05 06:23



Nhưng hình ảnh biến mất khi khung nhìn trở về từ bộ điều khiển sau khi gửi nó (trong MVC). Có thể giữ hình ảnh được chọn ngay cả khi kịch bản này không? - Clint Eastwood
@Sachin Prasad, chúng tôi có thể đặt số lượng tệp tối đa trong bản xem trước trước khi tải lên không - Super Model


Đây là một nhiều tệp phiên bản, dựa trên câu trả lời của Ivan Baev.

HTML

<input type="file" multiple id="gallery-photo-add">
<div class="gallery"></div>

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');
    });
});

Yêu cầu jQuery 1.8 do việc sử dụng $ .parseHTML, sẽ giúp giảm thiểu XSS.

Điều này sẽ làm việc ra khỏi hộp, và phụ thuộc duy nhất bạn cần là jQuery.


14
2017-12-14 15:30



Có thể có thẻ div xung quanh mỗi <img> và cách xóa chúng khỏi bản xem trước / tải lên không? - Rich
@Rich Chắc chắn, chỉ cần chơi với nó - Nino Škopac


Vâng. Điều đó là có thể.

Html

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

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);
        }    
    }

Bạn có thể làm được Bản thử trực tiếp từ đây.


11
2017-07-25 11:20



dotnetk.com/image-preview-before-upload - Krunal Sisodiya


Sạch sẽ và đơn giản JSfiddle

Điều này sẽ hữu ích khi bạn muốn Sự kiện được kích hoạt gián tiếp từ một nút div hoặc một nút.

<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>

7
2017-11-30 05:57



hoàn hảo, cảm ơn bạn đã chia sẻ và tôi có được url của hình ảnh xem trước đó không? tôi cần tải nó lên qua PHP. Cảm ơn! - xscoder
Chỉ cần lưu ý: Tôi không thể nhận tín dụng cho điều này nhưng bạn có thể sử dụng <label> và tránh javascript để xử lý nút bấm hoàn toàn. Kích hoạt đầu vào tệp bằng HTML / CSS thuần túy., và nó không phải là hacky cả. - Regular Joe


Ví dụ với nhiều hình ảnh sử dụng JavaScript (jQuery) và 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);
    });
}

Đánh dấu (HTML)

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

6
2017-11-26 06:33





Cách tạo một hàm tải tệp và kích hoạt sự kiện tùy chỉnh. Sau đó đính kèm một người nghe đến đầu vào. Bằng cách này, chúng tôi linh hoạt hơn để sử dụng tệp, không chỉ để xem trước hình ảnh.

/**
 * @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)

Có lẽ mã của tôi không tốt bằng một số người dùng nhưng tôi nghĩ bạn sẽ nhận được điểm của nó. Ở đây bạn có thể thấy thí dụ


4
2017-07-29 18:41





Sau đây là mã làm việc.

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

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]);
        }
    }

3
2018-01-06 16:19