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


86

Я намагаюся завантажити обране користувачем зображення через елемент.

Я додав обробник події 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 має значення id тегу, куди я хочу завантажити нове зображення.

Однак, схоже, завантаження ніколи не відбувається, і це не завантажує нічого в html.

Що я повинен зробити?


Відповіді:


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
  • Опера 12.02

Якщо файловий 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
Dai

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], створює a 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 Way

// 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 також дозволяє локальний доступ на додаток до можливості завантаження файлу.
Mike Morearty

Я завантажив виконуваний додаток Flash сюди, щоб ви могли його спробувати: morearty.com/preview/FileUploadTest.html
Mike Morearty

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>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.