Использование readAsDataURL () для предварительного просмотра изображений

jsFiddle URL-адресом: http://jsfiddle.net/Xotic750/AjtLx

работали над этим весь день и я не вижу проблемы. Вероятно, это связано с моим узким пониманием того, как работают объекты FileReader, но я пытаюсь использовать readAsDataURL() для получения изображений, выбранных пользователем, и предварительного просмотра их на экране в таблице. Все работает минус...вы угадали...просмотр...ну вроде того. Я думаю, что я близок, потому что предварительный просмотр будет работать, но это только отображает последнее изображение набора. Скажем, например, если я загрузил 6 изображений, то первая строка из 3 изображений будет сломана, вторая строка первые 2 будут сломаны, а затем окончательное 6-е изображение отобразит предварительный просмотр....Любые советы очень ценятся. Кроме того, как только это сработает, это может помочь другим, пытающимся сделать то же самое, потому что я искал решение этой проблемы, и я не могу ничего раскопать....

function PreviewImages() {
    var inputID = document.getElementById('input_clone');
    var totalImages = inputID.files.length;
    var imagesPerRow = 3;
    var numRows = totalImages / imagesPerRow;
    var row = "";
    var cell = "";
    var element1 = "";
    var elementID = "";


    for(var i = 0; i < numRows; i++){ //create rows
        row = document.getElementById('image_preview_table').insertRow(i);
        for(var ii = 0; ii < imagesPerRow; ii++){ //create cells
            cell = row.insertCell(ii);
            elementID = "img_" + ii;
            element1 = document.createElement("img");
            element1.name = elementID;
            element1.id = elementID
            cell.appendChild(element1);

            oFReader = new FileReader();

            oFReader.onload = function(oFREvent){
                var dataURI = oFREvent.target.result;
                var image = document.getElementById(elementID);
                image.src = dataURI;
            };

                oFReader.readAsDataURL(document.getElementById("input_clone").files[ii]);

    }
}
}

2 ответов


вот решение, совсем немного было сделано для вашего оригинала, чтобы заставить его работать, как вы, вероятно, заметите.

в CSS

div.rounded {
    width: 100%;
    border-style: solid;
    border-width: 1px;
    border-radius: 5px;
}
label {
    display: block;
}
input {
    display: block;
}
#previewTable {
    width: 100%;
}

HTML-код

<div id="imagesDiv" class="rounded">
    <label for="chooseFiles">Add Images</label>
    <input type="file" id="chooseFiles" multiple="multiple" />
    <table id="previewTable">
        <thead id="columns"></thead>
        <tbody id="previews"></tbody>
    </table>
</div>

в JavaScript

(function (global) {
    var imagesPerRow = 3,
        chooseFiles,
        columns,
        previews;

    function PreviewImages() {
        var row;

        Array.prototype.forEach.call(chooseFiles.files, function (file, index) {
            var cindex = index % imagesPerRow,
                oFReader = new FileReader(),
                cell,
                image;

            if (cindex === 0) {
                row = previews.insertRow(Math.ceil(index / imagesPerRow));
            }

            image = document.createElement("img");
            image.id = "img_" + index;
            image.style.width = "100%";
            image.style.height = "auto";
            cell = row.insertCell(cindex);
            cell.appendChild(image);

            oFReader.addEventListener("load", function assignImageSrc(evt) {
                image.src = evt.target.result;
                this.removeEventListener("load", assignImageSrc);
            }, false);

            oFReader.readAsDataURL(file);
        });
    }

    global.addEventListener("load", function windowLoadHandler() {
        global.removeEventListener("load", windowLoadHandler);
        chooseFiles = document.getElementById("chooseFiles");
        columns = document.getElementById("columns");
        previews = document.getElementById("previews");

        var row = columns.insertRow(-1),
            header,
            i;

        for (i = 0; i < imagesPerRow; i += 1) {
            header = row.insertCell(-1);
            header.style.width = (100 / imagesPerRow) + "%";
        }

        chooseFiles.addEventListener("change", PreviewImages, false);
    }, false);
}(window));

On jsfiddle


проблема с вашим кодом: readAsDataURL() является асинхронным, вы должны подождать, пока он не закончит чтение, прежде чем вызывать второе чтение или создавать новый экземпляр, вызывая new FileReader().

ответ Xotic750 работает, потому что он создает один FileReader для каждого изображения, в то время как вы использовали только один FileReader.

но использование FileReader для предварительного просмотра изображений не является хорошим выбором, как FileReader.readAsDataURL() преобразует все изображение в большую строку (в форма " данные: image / jpeg; base64,/9j / 4SVaRXhpZgAAS......"), и вы показываете изображение, помещая всю строку данных изображения в img.атрибут src, если ваше изображение большое, вы рискуете исчерпать память.

img.src должен содержать url изображения, а не данные изображения, хотя вы можете назначить url, содержащий все данные изображения через img.src = " данные: изображение / jpeg;......".

Итак, вы должны использовать window.URL-АДРЕС.createObjectURL () для создания url-адреса обратитесь к локальному изображению и назначьте этот url-адрес img.src:

...
img.src = window.URL.createObjectURL(fileInput.files[i]);
...