Laden eines Bildes in ein <img> aus <Eingabedatei>

86

Ich versuche, ein vom Benutzer ausgewähltes Bild über ein Element zu laden.

Ich habe dem Eingabeelement einen onchange-Ereignishandler wie folgt hinzugefügt:

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

und die Vorschau_2 Funktion ist:

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

Dabei hat outImage den ID-Wert des Tags, an dem das neue Bild geladen werden soll.

Es scheint jedoch, dass das Onload niemals stattfindet und nichts in das HTML geladen wird.

Was soll ich machen?

Valentina
quelle

Antworten:

102

In Browsern, die die Datei-API unterstützen , können Sie den FileReader- Konstruktor verwenden, um Dateien zu lesen, sobald sie vom Benutzer ausgewählt wurden.

Beispiel

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

Browser-Unterstützung

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

Wenn die Datei-API nicht unterstützt wird, können Sie (in den meisten sicherheitsbewussten Browsern) weder den vollständigen Pfad einer Datei aus einem Dateieingabefeld abrufen noch auf die Daten zugreifen. Die einzig praktikable Lösung wäre, das Formular an einen versteckten Iframe zu senden und die Datei vorab auf den Server hochzuladen. Wenn diese Anforderung abgeschlossen ist, können Sie den Quellcode des Bildes auf den Speicherort der hochgeladenen Datei setzen.

Andy E.
quelle
Richtig, es gibt also keine Möglichkeit, ein vom Benutzer ausgewähltes Bild so einfach hochzuladen, wie es sich anhört ...?
Valentina
1
Ja, ich suche nach X-Browser-Lösungen, daher werde ich es mit der Serveroption versuchen. Vielen Dank!
Valentina
1
Ich frage mich, warum dies in eine DataURL und nicht nur in eine Objekt-URL konvertiert wird.
ShrekOverflow
4
Wenn Sie die synchrone Version möchten, können Sie Folgendes verwenden : URL.createObjectURL(document.getElementById("fileInput").files[0]);.
15онстантин Ван
1
@ КонстантинВан Sie müssen sicherstellen, dass Sie anrufen URL.revokeObjectURL, um Speicherverluste zu vermeiden! developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL
Dai
53

Wie iEamin in seiner Antwort sagte, unterstützt HTML 5 dies jetzt. Der Link, den er gegeben hat, http://www.html5rocks.com/en/tutorials/file/dndfiles/ , ist ausgezeichnet. Hier ist eine minimale Stichprobe, die auf den Stichproben an dieser Site basiert. Weitere Beispiele finden Sie auf dieser Site.

Fügen Sie onchangeIhrem HTML einen Ereignis-Listener hinzu:

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

Erstellen Sie ein Bild-Tag mit einer ID (ich gebe height=200an, um sicherzustellen, dass das Bild auf dem Bildschirm nicht zu groß ist):

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

Hier ist das JavaScript des onchangeEreignis-Listeners. Es nimmt das FileObjekt, das als übergeben wurde event.target.files[0], erstellt ein FileReader, um seinen Inhalt zu lesen, und richtet einen neuen Ereignis-Listener ein, um die resultierende data:URL dem imgTag zuzuweisen :

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);
}
Mike Morearty
quelle
Toller Link! Der Code, den Sie für das Skript präsentieren, ist jedoch nicht definiert.
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">

Das funktioniert bei mir in jQuery.

Asghar
quelle
Wie verwende ich das, wenn 'imgload' und 'imgshow' nicht im Voraus definiert wurden? Angenommen, ich habe 5 Paare von Dateieingaben und Bildhaltern vom Server zurückgegeben, und ihre jeweiligen IDs werden basierend auf einem Index generiert, der auch vom Servercode zurückgegeben wird.
Ivan
5

ES2017 Weg

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

nkitku
quelle
1

Andy E hat Recht, dass es keine HTML-basierte Möglichkeit gibt, dies zu tun *; Wenn Sie jedoch bereit sind, Flash zu verwenden, können Sie dies tun. Das Folgende funktioniert zuverlässig auf Systemen, auf denen Flash installiert ist. Wenn Ihre App auf dem iPhone funktionieren muss, benötigen Sie natürlich eine HTML-basierte Fallback-Lösung.

* ( Update 22.04.2013: HTML unterstützt dies jetzt in HTML5. Siehe die anderen Antworten.)

Das Hochladen von Flash bietet noch weitere Vorteile: Mit Flash können Sie einen Fortschrittsbalken anzeigen, während der Upload einer großen Datei fortschreitet. (Ich bin mir ziemlich sicher, dass Google Mail dies so macht, indem es Flash hinter den Kulissen verwendet, obwohl ich mich darin möglicherweise irre.)

Hier ist ein Beispiel für eine Flex 4-App, mit der der Benutzer eine Datei auswählen und dann anzeigen kann:

<?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>
Mike Morearty
quelle
Zur Verdeutlichung für diejenigen, die sich Sorgen um die Sicherheit machen: Mit Flash können Sie nicht auf eine lokale Datei zugreifen, sondern nur auf eine lokale Datei, auf die der Benutzer explizit und interaktiv hingewiesen hat. Dies ähnelt der Funktionsweise von HTML (mit der Sie explizit angegebene Dateien auf den Server hochladen können), mit der Ausnahme, dass Flash neben der Möglichkeit zum Hochladen der Datei auch den lokalen Zugriff ermöglicht.
Mike Morearty
Ich habe die ausführbare Flash-App hier hochgeladen, damit Sie sie ausprobieren können: 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>

Saeed saeeyd
quelle