从<输入文件>将图像加载到<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值,我要在其中加载新图片。

但是,似乎永远不会发生onload,并且不会向html加载任何内容。

我该怎么办?


Answers:


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

如果不支持File API,则您(在大多数注重安全性的浏览器中)无法从文件输入框中获取文件的完整路径,也无法访问数据。唯一可行的解​​决方案是将表单提交到隐藏的iframe,然后将文件预上传到服务器。然后,当该请求完成时,您可以将图像的src设置为上载文件的位置。


是的,所以我无法像听起来那样简单地上传用户选择的图像?
瓦伦蒂娜(Valentina)2010年

1
是的,我正在寻找x浏览器解决方案,因此我想尝试使用server选项。非常感谢你!
瓦伦蒂娜(Valentina)2010年

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)">

制作一个带有ID的图片标签(我指定height=200要确保图片在屏幕上不会太大):

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

这是onchange事件监听器的JavaScript 。它采用File传递为的对象event.target.files[0],构造一个aFileReader来读取其内容,并设置一个新的事件侦听器以将结果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 2015年

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对从服务器返回的文件输入和图像持有人,并且它们各自的id是根据也从服务器代码返回的某个索引生成的。
伊万

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

Andy E是正确的,因为没有基于HTML的方式可以做到这一点*;但是如果您愿意使用Flash,则可以这样做。以下内容在已安装Flash的系统上可靠地运行。如果您的应用程序需要在iPhone上运行,那么您当然需要基于HTML的后备解决方案。

*(2013年4月22日更新: HTML5现在已支持HTML。请参阅其他答案。)

Flash上​​传还具有其他优点-Flash使您能够在大型文件的上传过程中显示进度条。(我敢肯定,通过幕后使用Flash,Gmail就是这样做的,尽管我对此可能是错的。)

这是一个示例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 2010年

我在此处上传了可执行Flash应用程序,因此您可以尝试一下:morearty.com/preview/FileUploadTest.html
Mike Morearty 2010年

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>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.