Caricamento di un'immagine in un <img> da <file di input>


90

Sto cercando di caricare un'immagine selezionata dall'utente tramite un elemento.

Ho aggiunto un gestore di eventi onchange all'elemento di input in questo modo:

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

e la funzione 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;
}

dove outImage ha il valore id del tag in cui voglio che la nuova immagine venga caricata.

Tuttavia, sembra che l'onload non avvenga mai e non carichi nulla nell'html.

Cosa dovrei fare?


Risposte:


106

Nei browser che supportano l' API File , è possibile utilizzare il costruttore FileReader per leggere i file una volta che sono stati selezionati dall'utente.

Esempio

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

Supporto del browser

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

Laddove l'API File non è supportata, non è possibile (nella maggior parte dei browser attenti alla sicurezza) ottenere il percorso completo di un file da una casella di input del file, né accedere ai dati. L'unica soluzione praticabile sarebbe inviare il modulo a un iframe nascosto e avere il file precaricato sul server. Quindi, quando la richiesta è completa, puoi impostare il codice src dell'immagine sulla posizione del file caricato.


giusto, quindi non è possibile caricare un'immagine selezionata dall'utente semplicemente come sembra ...?
Valentina

1
sì, sto cercando soluzioni x-browser, quindi penso che proverò usando l'opzione server. Grazie mille!
Valentina

1
Mi chiedo perché convertirlo in un DataURL e non solo in un oggetto URL?
ShrekOverflow

5
Se si desidera la versione sincrona, è possibile utilizzare: URL.createObjectURL(document.getElementById("fileInput").files[0]);.
Константин Ван

1
@ КонстантинВан Devi assicurarti di chiamare URL.revokeObjectURLper evitare perdite di memoria! developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL
Dai

53

Come ha detto iEamin nella sua risposta, HTML 5 ora lo supporta. Il collegamento che ha fornito, http://www.html5rocks.com/en/tutorials/file/dndfiles/ , è eccellente. Di seguito è riportato un esempio minimo basato sugli esempi in quel sito, ma vedere quel sito per esempi più approfonditi.

Aggiungi un onchangelistener di eventi al tuo HTML:

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

Crea un tag immagine con un ID (lo sto specificando height=200per assicurarmi che l'immagine non sia troppo grande sullo schermo):

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

Ecco il JavaScript del onchangelistener di eventi. Prende l' Fileoggetto che è stato passato come event.target.files[0], costruisce a FileReaderper leggere il suo contenuto e imposta un nuovo listener di eventi per assegnare l' data:URL risultante al imgtag:

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

Ottimo collegamento! Il codice che presenti per lo script non è però definito.
rashadb

14

$('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">

Questo funziona per me in jQuery.


Come usarlo nel caso in cui "imgload" e "imgshow" non siano stati definiti in anticipo? Diciamo che ho 5 coppie di input di file e detentori di immagini restituiti dal server e i loro rispettivi ID vengono generati in base a un indice restituito anche dal codice del server.
Ivan

7

Modo 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

Andy E ha ragione sul fatto che non esiste un modo basato su HTML per farlo *; ma se vuoi usare Flash, puoi farlo. Quanto segue funziona in modo affidabile sui sistemi in cui è installato Flash. Se la tua app deve funzionare su iPhone, ovviamente avrai bisogno di una soluzione basata su HTML di riserva.

* ( Aggiornamento 22/04/2013: HTML ora lo supporta, in HTML5. Vedi le altre risposte.)

Il caricamento di Flash ha anche altri vantaggi: Flash ti dà la possibilità di mostrare una barra di avanzamento mentre il caricamento di un file di grandi dimensioni procede. (Sono abbastanza sicuro che sia così che fa Gmail, utilizzando Flash dietro le quinte, anche se potrei sbagliarmi su questo.)

Ecco un'app Flex 4 di esempio che consente all'utente di scegliere un file e quindi di visualizzarlo:

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

Per chiarire, per coloro che sono preoccupati per la sicurezza: Flash non ti consente di accedere a NESSUN file locale - ti consente solo di accedere a un file locale che è stato esplicitamente, interattivamente puntato dall'utente. Questo è simile a quello che fa l'HTML (consente di caricare qualsiasi file specificato esplicitamente sul server), tranne per il fatto che Flash consente anche l'accesso locale oltre alla possibilità di caricare il file.
Mike Morearty,

Ho caricato l'app eseguibile Flash qui in modo che tu possa provarla: 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>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.