Jon*_*nas 47 javascript drawimage fileapi html5-canvas
我想在画布上绘制一个用HTML5 File API打开的图像.
在该handleFiles(e)方法中,我可以访问文件,e.target.files[0]但我无法直接使用该图像drawImage.如何从HTML5画布上的File API中绘制图像?
这是我用过的代码:
<!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>
Run Code Online (Sandbox Code Playgroud)
pim*_*vdb 74
你有一个File不是图像的实例.
要获取a的内容File,请使用a FileReader.然后将内容传递给一个Image实例,该实例可以在画布上绘制:http://jsfiddle.net/t7mv6/.
要获取图像,请使用new Image().该src需求是一个URL引用到选定的File.您可以使用URL.createObjectURL获取引用Blob(a File也是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]);
Run Code Online (Sandbox Code Playgroud)
注意:确保在完成后撤消对象URL,否则会泄漏内存.如果你没有做任何事情太疯狂了,你可以贴URL.revokeObjectURL(img.src)在img.onload函数.
参考文献:
Ray*_*nos 12
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;
}
Run Code Online (Sandbox Code Playgroud)
您也可以使用FileReader而不是创建对象URL.
该FileReader有稍微好一点的浏览器支持.
该FileReader方法适用于FF6/Chrome.我不确定设置Img.src为a Blob是否有效且跨浏览器.
创建对象URL是正确的方法.
编辑:
正如提交window.URL支持中提到的那样,离线似乎在FF6/Chrome中不可用.
这是一个完整的示例(Fiddle)使用FileReader(如 Raynos 提到的,它具有更好的浏览器支持)。在此示例中,我还缩放画布以适合图像。
在现实生活中的示例中,您可以将图像缩放到某个最大值,这样您的表单就不会爆炸;-)。这是一个缩放的示例 (Fiddle)。
var URL = window.webkitURL || window.URL;
window.onload = function() {
var input = document.getElementById('input');
input.addEventListener('change', handleFiles, false);
// set original canvas dimensions as max
var canvas = document.getElementById('canvas');
canvas.dataMaxWidth = canvas.width;
canvas.dataMaxHeight = canvas.height;
}
function handleFiles(e) {
var ctx = document.getElementById('canvas').getContext('2d');
var reader = new FileReader();
var file = e.target.files[0];
// load to image to get it's width/height
var img = new Image();
img.onload = function() {
// setup scaled dimensions
var scaled = getScaledDim(img, ctx.canvas.dataMaxWidth, ctx.canvas.dataMaxHeight);
// scale canvas to image
ctx.canvas.width = scaled.width;
ctx.canvas.height = scaled.height;
// draw image
ctx.drawImage(img, 0, 0
, ctx.canvas.width, ctx.canvas.height
);
}
// this is to setup loading the image
reader.onloadend = function () {
img.src = reader.result;
}
// this is to read the file
reader.readAsDataURL(file);
}
// returns scaled dimensions object
function getScaledDim(img, maxWidth, maxHeight) {
var scaled = {
ratio: img.width / img.height,
width: img.width,
height: img.height
}
if (scaled.width > maxWidth) {
scaled.width = maxWidth;
scaled.height = scaled.width / scaled.ratio;
}
if (scaled.height > maxHeight) {
scaled.height = maxHeight;
scaled.width = scaled.height / scaled.ratio;
}
return scaled;
}Run Code Online (Sandbox Code Playgroud)
canvas {
border:1px solid black
}Run Code Online (Sandbox Code Playgroud)
<input type="file" id="input"/>
<div>
<canvas width="400" height="300" id="canvas"/>
</div>Run Code Online (Sandbox Code Playgroud)