Memuat gambar ke <img> dari <file input>

90

Saya mencoba memuat gambar yang dipilih oleh pengguna melalui sebuah elemen.

Saya menambahkan event handler onchange ke elemen input seperti ini:

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

dan fungsi preview_2 adalah:

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

di mana outImage memiliki nilai id dari tag di mana saya ingin gambar baru dimuat.

Namun, tampaknya pemuatan tidak pernah terjadi dan tidak memuat apa pun ke html.

Apa yang harus saya lakukan?

Valentina
sumber

Jawaban:

106

Di browser yang mendukung API File , Anda dapat menggunakan konstruktor FileReader untuk membaca file setelah dipilih oleh pengguna.

Contoh

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

Dukungan browser

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

Jika API File tidak didukung, Anda tidak dapat (di sebagian besar browser yang sadar keamanan) mendapatkan jalur lengkap file dari kotak input file, Anda juga tidak dapat mengakses data. Satu-satunya solusi yang layak adalah mengirimkan formulir ke iframe tersembunyi dan file tersebut telah diunggah sebelumnya ke server. Kemudian, ketika permintaan itu selesai, Anda dapat menyetel src dari gambar ke lokasi file yang diunggah.

Andy E
sumber
benar, jadi tidak mungkin saya dapat mengunggah gambar yang dipilih dari pengguna sesederhana kedengarannya ...?
Valentina
1
ya, saya sedang mencari solusi x-browser jadi saya rasa saya akan mencobanya menggunakan opsi server. Terima kasih banyak!
Valentina
1
Saya bertanya-tanya mengapa mengubahnya menjadi DataURL dan bukan hanya url objek?
ShrekOverflow
5
Jika Anda ingin versi sinkron, Anda dapat menggunakan: URL.createObjectURL(document.getElementById("fileInput").files[0]);.
Константин Ван
1
@ КонстантинВан Anda harus memastikan bahwa Anda menelepon URL.revokeObjectURLuntuk mencegah kebocoran memori! developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL
Dai
53

Seperti yang dikatakan iEamin dalam jawabannya, HTML 5 sekarang mendukung ini. Tautan yang dia berikan, http://www.html5rocks.com/en/tutorials/file/dndfiles/ , sangat bagus. Berikut adalah contoh minimal berdasarkan contoh di situs itu, tetapi lihat situs itu untuk contoh yang lebih menyeluruh.

Tambahkan onchangeevent listener ke HTML Anda:

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

Buat tag gambar dengan id (saya menentukan height=200untuk memastikan gambar tidak terlalu besar di layar):

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

Berikut adalah JavaScript onchangepemroses acara. Ini mengambil Fileobjek yang diteruskan sebagai event.target.files[0], membuat FileReaderuntuk membaca isinya, dan menyiapkan event listener baru untuk menetapkan data:URL yang dihasilkan ke 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);
}
Mike Morearty
sumber
Tautan bagus! Kode yang Anda berikan untuk skrip tidak ditentukan.
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">

Itu berhasil untuk saya di jQuery.

asghar
sumber
Bagaimana cara menggunakan ini jika 'imgload' dan 'imgshow' tidak ditentukan sebelumnya? Katakanlah saya memiliki 5 pasang input file dan pemegang gambar yang dikembalikan dari server, dan id masing-masing dihasilkan berdasarkan beberapa indeks yang juga dikembalikan dari kode server.
Ivan
6

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

nkitku
sumber
1

Andy E benar bahwa tidak ada cara berbasis HTML untuk melakukan ini *; tetapi jika Anda ingin menggunakan Flash, Anda dapat melakukannya. Berikut ini bekerja dengan andal pada sistem yang telah menginstal Flash. Jika aplikasi Anda perlu berfungsi di iPhone, maka tentu saja Anda memerlukan solusi berbasis HTML fallback.

* ( Pembaruan 4/22/2013: HTML sekarang mendukung ini, di HTML5. Lihat jawaban lainnya.)

Pengunggahan Flash juga memiliki keuntungan lain - Flash memberi Anda kemampuan untuk menampilkan bilah kemajuan saat pengunggahan file besar berlangsung. (Saya cukup yakin begitulah cara Gmail melakukannya, dengan menggunakan Flash di belakang layar, meskipun saya mungkin salah tentang itu.)

Berikut ini contoh aplikasi Flex 4 yang memungkinkan pengguna memilih file, lalu menampilkannya:

<?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
sumber
Untuk memperjelas, bagi mereka yang mengkhawatirkan keamanan: Flash tidak mengizinkan Anda untuk mengakses file lokal APA PUN - ini hanya memungkinkan Anda untuk mengakses file lokal yang telah secara eksplisit diarahkan oleh pengguna. Ini mirip dengan apa yang HTML lakukan (ini memungkinkan Anda mengunggah file yang ditentukan secara eksplisit ke server), kecuali bahwa Flash juga memungkinkan akses lokal selain kemampuan untuk mengunggah file.
Mike Morearty
Saya mengunggah aplikasi Flash yang dapat dieksekusi di sini sehingga Anda dapat mencobanya: 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
sumber