Загрузка изображения в <img> из <входного файла>

87

Я пытаюсь загрузить изображение, выбранное пользователем, через элемент.

Я добавил обработчик события onchange к элементу ввода следующим образом:

<input type="file" name="picField" id="picField" size="24" onchange="preview_2(this);" alt=""/>

а функция preview_2:

var outImage ="imagenFondo";
function preview_2(what){
    globalPic = new Image();
    globalPic.onload = function() {
        document.getElementById(outImage).src = globalPic.src;
    }
    globalPic.src=what.value;
}

где outImage имеет значение идентификатора тега, в который я хочу загрузить новое изображение.

Однако похоже, что загрузка никогда не происходит и ничего не загружает в html.

Что я должен делать?

Валентина
источник
1
дублирует stackoverflow.com/questions/4459379/… ?
Challet 05

Ответы:

102

В браузерах, поддерживающих File API , вы можете использовать конструктор FileReader для чтения файлов после того, как они были выбраны пользователем.

пример

document.getElementById('picField').onchange = function (evt) {
    var tgt = evt.target || window.event.srcElement,
        files = tgt.files;

    // FileReader support
    if (FileReader && files && files.length) {
        var fr = new FileReader();
        fr.onload = function () {
            document.getElementById(outImage).src = fr.result;
        }
        fr.readAsDataURL(files[0]);
    }

    // Not supported
    else {
        // fallback -- perhaps submit the input to an iframe and temporarily store
        // them on the server until the user's session ends.
    }
}

Поддержка браузера

  • IE 10
  • Safari 6.0.2
  • Chrome 7
  • Firefox 3.6
  • Opera 12.02

Если File API не поддерживается, вы не можете (в большинстве браузеров, заботящихся о безопасности) получить полный путь к файлу из поля ввода файла и не можете получить доступ к данным. Единственным жизнеспособным решением было бы отправить форму в скрытый iframe и предварительно загрузить файл на сервер. Затем, когда этот запрос завершится, вы можете установить src изображения в местоположение загруженного файла.

Энди Э
источник
верно, поэтому я не могу загрузить изображение, выбранное пользователем, так же просто, как оно звучит ...?
Валентина
1
да, я ищу решения для x-браузера, поэтому я думаю, что попробую, используя опцию сервера. Большое спасибо!
Валентина
1
Интересно, зачем преобразовывать это в DataURL, а не только в URL-адрес объекта?
ShrekOverflow
4
Если вы хотите синхронную версию, вы можете использовать: URL.createObjectURL(document.getElementById("fileInput").files[0]);.
Константин Ван
1
@ КонстантинВан Вы должны звонить, URL.revokeObjectURLчтобы предотвратить утечку памяти! developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL
Дай,
53

Как сказал iEamin в своем ответе, HTML 5 теперь поддерживает это. Ссылка, которую он дал, http://www.html5rocks.com/en/tutorials/file/dndfiles/ , превосходна. Вот минимальный образец, основанный на образцах на этом сайте, но см. Этот сайт для более подробных примеров.

Добавьте onchangeпрослушиватель событий в свой HTML:

<input type="file" onchange="onFileSelected(event)">

Создайте тег изображения с идентификатором (я указываю, height=200чтобы изображение на экране не было слишком большим):

<img id="myimage" height="200">

Вот код JavaScript onchangeпрослушивателя событий. Он берет Fileобъект, который был передан как event.target.files[0], создает FileReaderдля чтения его содержимого и настраивает новый прослушиватель событий, чтобы назначить результирующий data:URL-адрес imgтегу:

function onFileSelected(event) {
  var selectedFile = event.target.files[0];
  var reader = new FileReader();

  var imgtag = document.getElementById("myimage");
  imgtag.title = selectedFile.name;

  reader.onload = function(event) {
    imgtag.src = event.target.result;
  };

  reader.readAsDataURL(selectedFile);
}
Майк Морарти
источник
Отличная ссылка! Однако код, который вы представляете для сценария, не определен.
rashadb
13

$('document').ready(function () {
    $("#imgload").change(function () {
        if (this.files && this.files[0]) {
            var reader = new FileReader();
            reader.onload = function (e) {
                $('#imgshow').attr('src', e.target.result);
            }
            reader.readAsDataURL(this.files[0]);
        }
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" id="imgload" >
<img src="#" id="imgshow" align="left">

У меня это работает в jQuery.

Асгар
источник
Как это использовать, если imgload и imgshow не определены заранее? Скажем, у меня есть 5 пар входных файлов и держателей изображений, возвращаемых с сервера, и их соответствующие идентификаторы генерируются на основе некоторого индекса, который также возвращается из кода сервера.
Иван
5

ES2017 Путь

// convert file to a base64 url
const readURL = file => {
    return new Promise((res, rej) => {
        const reader = new FileReader();
        reader.onload = e => res(e.target.result);
        reader.onerror = e => rej(e);
        reader.readAsDataURL(file);
    });
};

// for demo
const fileInput = document.createElement('input');
fileInput.type = 'file';
const img = document.createElement('img');
img.attributeStyleMap.set('max-width', '320px');
document.body.appendChild(fileInput);
document.body.appendChild(img);

const preview = async event => {
    const file = event.target.files[0];
    const url = await readURL(file);
    img.src = url;
};

fileInput.addEventListener('change', preview);

нкитку
источник
1

Энди Э прав, что не существует способа сделать это на основе HTML *; но если вы хотите использовать Flash, вы можете это сделать. Следующее работает надежно в системах с установленным Flash. Если ваше приложение должно работать на iPhone, вам, конечно же, понадобится запасное решение на основе HTML.

* ( Обновление от 22.04.2013: HTML теперь поддерживает это в HTML5. См. Другие ответы.)

Загрузка Flash имеет и другие преимущества - Flash дает вам возможность отображать индикатор выполнения по мере того, как идет загрузка большого файла. (Я почти уверен, что Gmail делает это именно так, используя Flash за кадром, хотя я могу ошибаться в этом.)

Вот пример приложения Flex 4, которое позволяет пользователю выбрать файл и затем отобразить его:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
               creationComplete="init()">
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <s:Button x="10" y="10" label="Choose file..." click="showFilePicker()" />
    <mx:Image id="myImage" x="9" y="44"/>
    <fx:Script>
        <![CDATA[
            private var fr:FileReference = new FileReference();

            // Called when the app starts.
            private function init():void
            {
                // Set up event handlers.
                fr.addEventListener(Event.SELECT, onSelect);
                fr.addEventListener(Event.COMPLETE, onComplete);
            }

            // Called when the user clicks "Choose file..."
            private function showFilePicker():void
            {
                fr.browse();
            }

            // Called when fr.browse() dispatches Event.SELECT to indicate
            // that the user has picked a file.
            private function onSelect(e:Event):void
            {
                fr.load(); // start reading the file
            }

            // Called when fr.load() dispatches Event.COMPLETE to indicate
            // that the file has finished loading.
            private function onComplete(e:Event):void
            {
                myImage.data = fr.data; // load the file's data into the Image
            }
        ]]>
    </fx:Script>
</s:Application>
Майк Морарти
источник
Чтобы уточнить, для тех, кто беспокоится о безопасности: Flash не позволяет вам получить доступ к ЛЮБОМУ локальному файлу - он позволяет вам получить доступ только к локальному файлу, на который пользователь явно, интерактивно указал. Это похоже на то, что делает HTML (он позволяет вам загружать любой явно указанный файл на сервер), за исключением того, что Flash также позволяет локальный доступ в дополнение к возможности загрузки файла.
Майк Морарти,
Я загрузил здесь исполняемое приложение Flash, чтобы вы могли его попробовать: morearty.com/preview/FileUploadTest.html
Майк Морарти
1

var outImage ="imagenFondo";
function preview_2(obj)
{
	if (FileReader)
	{
		var reader = new FileReader();
		reader.readAsDataURL(obj.files[0]);
		reader.onload = function (e) {
		var image=new Image();
		image.src=e.target.result;
		image.onload = function () {
			document.getElementById(outImage).src=image.src;
		};
		}
	}
	else
	{
		    // Not supported
	}
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>preview photo</title>
</head>

<body>
<form>
	<input type="file" onChange="preview_2(this);"><br>
	<img id="imagenFondo" style="height: 300px;width: 300px;">
</form>
</body>
</html>

Саид Саид
источник