Нужно ли нам * использовать data: URI (readAsDataURL) для использования объектов File св JavaScript? - PullRequest
0 голосов
/ 25 февраля 2019

Я понимаю, что в настоящее время общепринятый метод создания элемента <img /> в JavaScript из клиентского объекта File выглядит примерно так.

(Объект File может возникнуть в результате перетаскивания файла-and-drop или <input type="file" /> change событие.)

function showImageFile( file: File ): void {

    let rdr = new FileReader();
    rdr.readAsDataURL( file );
    rdr.onloadend = function() {
        let img = document.createElement('img');
        img.src = rdr.result;
        document.body.appendChild( img );
    };
}

Мне это не нравится - идея сериализации того, что может быть мультимегабайтным изображением, в строку в кодировке base64 (таким образом, используя 1,3x больше памяти поверх существующего объекта File), а также понеся затраты на десериализацию строки обратно в элемент <img /> - в конечном итоге это вызовет как минимум 3 экземпляраданные изображения должны существовать в памяти.Мне это кажется очень расточительным и неэффективным, и приложения JavaScript уже имеют плохую репутацию из-за чрезмерного потребления памяти.

Я заметил, что для элементов <video> и <audio> (HTMLMediaElement), которые MDN рекомендует делатьчто-то вроде этого:

function showVideoFile( file: File ): void {

    let video = document.createElement('video');
    video.srcObject = URL.createObjectURL( file ); // createObjectURL creates a URI alias to the existing file instance in-memory
}

(с оговоркой, что если srcObject когда-либо будет заменен или удален элемент video, предыдущий objectURL должен быть вручную освобожден с использованием revokeObjectURL.

Есть ли способ сделать то же самое для <img />? (Я не вижу свойства srcObject на HTMLImageElement, а HTMLImageElement не является производным от HTMLMediaElement). Поиск в Интернете по запросу "javascriptфайлы изображений без URI данных "к сожалению, возвращает только страницы о readAsDataURL, что противоположно тому, что я хочу.

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

Пожертвовав больше минут из-за темных и грязных информационных рудников в Google, я обнаружил кусок угля в этой статье за ​​декабрь 2014 года http://bytes.schibsted.com/the-magic-of-createobjecturl/, в которой говорится, что атрибут HTMLImageElement src делает фактически принимает URI объекта (тьфу!)

MDN также размещает его на своем веб-сайте, хотя и несколько похоронен: https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications#Example_Using_object_URLs_to_display_images

Короче говоря, моя функция showImageFile может быть обновлена ​​следующим образом:итак:

function showImageFile( file: File ): void {

    let objectURI = URL.createObjectURL( file ); // looks like "blob:http://mywebsite/{guid}"

    let img = document.createElement('img');
    img.src = objectURI ;
    document.body.appendChild( img );
}

Или, если элемент img будет использоваться повторно:

var img: HTMLImageElement;

function showImageFile( file: File ): void {

    let oldSrc = img.src;

    let objectURI = URL.createObjectURL( file );

    img.src = objectURI;

    if( oldSrc ) URL.revokeObjectURL( oldSrc );
}
0 голосов
/ 25 февраля 2019

Вы устанавливаете его ... src.

document.getElementById('file').onchange = function () {
    if (this.files.length !== 0) {
        var img = new Image();
        img.src = URL.createObjectURL(this.files[0]);
        document.body.appendChild(img);
    }
};
<input type="file" id="file" accept="image/*" />
...