Javascript 如何从 Canvas 上的 HTML5 文件 API 绘制图像?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6775767/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 23:08:32  来源:igfitidea点击:

How can I draw an image from the HTML5 File API on Canvas?

javascriptcanvasdrawimagefileapi

提问by Jonas

I would like to draw an image opened with the HTML5 File API on a canvas.

我想在画布上绘制使用 HTML5 文件 API 打开的图像。

In the handleFiles(e)method, I can access the File with e.target.files[0]but I can't draw that image directly using drawImage. How do I draw an image from the File API on HTML5 canvas?

在该handleFiles(e)方法中,我可以使用 访问文件,e.target.files[0]但无法直接使用drawImage. 如何从 HTML5 画布上的 File API 绘制图像?

Here is the code I have used:

这是我使用的代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script>
window.onload = function() {
    var input = document.getElementById('input');
    input.addEventListener('change', handleFiles);
}

function handleFiles(e) {
    var ctx = document.getElementById('canvas').getContext('2d');
    ctx.drawImage(e.target.files[0], 20,20);
    alert('the image is drawn');
}
</script>
</head>
<body>
<h1>Test</h1>
<input type="file" id="input"/>
<canvas width="400" height="300" id="canvas"/>
</body>
</html>

回答by pimvdb

You have a Fileinstance which is not an image.

您有一个File不是图像的实例。

To get contents of a File, use a FileReader. Then pass the contents to an Imageinstance, which can be drawn on a canvas: http://jsfiddle.net/t7mv6/.

要获取 a 的内容File,请使用 a FileReader。然后将内容传递给Image可以在画布上绘制的实例:http: //jsfiddle.net/t7mv6/

To get an image, use new Image(). The srcneeds to be an URL referencing to the selected File. You can use URL.createObjectURLto get an URL referencing to a Blob(a Fileis also a Blob): http://jsfiddle.net/t7mv6/86/.

要获取图像,请使用new Image(). 该src需求是一个URL引用到选定的File。您可以使用URL.createObjectURL获取引用 a Blob(aFile也是 a Blob)的 URL :http: //jsfiddle.net/t7mv6/86/

var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image;
img.onload = function() {
    ctx.drawImage(img, 20,20);
    alert('the image is drawn');
}
img.src = URL.createObjectURL(e.target.files[0]);

Note:be sure to revoke the object url when you are done with it otherwise you'll leak memory. If you're not doing anything too crazy, you can just stick a URL.revokeObjectURL(img.src)in the img.onloadfunction.

注意:一定要在完成后撤消对象 url,否则会泄漏内存。如果你不做任何太疯狂的事情,你可以URL.revokeObjectURL(img.src)img.onload函数中添加 a 。

References:

参考:

回答by Raynos

Live Example

现场示例

function handleFiles(e) {
    var ctx = document.getElementById('canvas').getContext('2d');
    var url = URL.createObjectURL(e.target.files[0]);
    var img = new Image();
    img.onload = function() {
        ctx.drawImage(img, 20, 20);    
    }
    img.src = url;   
}

window.URL.createObjectUrldocs

window.URL.createObjectUrl文档

You could also use the FileReaderinstead to create the object URL.

您还可以使用FileReader代替来创建对象 URL。

The FileReaderhas slightly better browser support.

FileReader有稍微好一点的浏览器支持。

The FileReaderapproach works in FF6 / Chrome. I'm not certain whether setting Img.srcto a Blobis valid and cross-browser though.

FileReader方法适用于 FF6/Chrome。我不确定设置Img.src为 aBlob是否有效和跨浏览器。

Creating object urls is the correct way to do it.

创建对象 url 是正确的方法。

Edit:

编辑:

As mentioned in the commment window.URLsupport whilst offline seems unavailable in FF6/Chrome.

正如评论window.URL支持中提到的,离线似乎在 FF6/Chrome 中不可用。

回答by Nux

Here is a complete example (Fiddle)using FileReader(which has better browser support as mentioned by Raynos). In this example I also scale Canvas to fit the image.

这是一个完整的示例(小提琴)using FileReader(它具有更好的浏览器支持,正如 Raynos 所提到的)。在这个例子中,我还缩放 Canvas 以适应图像。

In real life example you might scale the image to some maximum so that your form will not blow up ;-). Here is an example with scaling (Fiddle).

在现实生活中的示例中,您可能会将图像缩放到某个最大值,这样您的表单就不会炸毁 ;-)。这是一个缩放示例 (Fiddle)