我有一个html画布,显示在输入中选择图像时的图像预览。这适用于Chrome,但我似乎无法在Safari中使用它。具体来说 - 在Safari中,onchange="previewFile()"
似乎没有调用previewFile函数。
<canvas id="canvas" width="0" height="0"></canvas>
<h2>Upload a photo </h2>
<input type="file" onchange="previewFile()"><br>
<script type="text/javascript">
// setup the canvas
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// grab the photo and display in canvas
var photo = new Image();
function previewFile() {
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener("load", function () {
photo.src = reader.result;
canvas.height = photo.height;
canvas.width = photo.width;
ctx.drawImage(photo,0,0);
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
</script>
&#13;
答案 0 :(得分:1)
您的问题当然是因为您在尝试在画布上绘制图像之前没有等待图像已加载。
即使源是dataURI,图像的加载也是异步的,因此您需要将图形操作包装在图像的onload
事件中。
var photo = new Image();
photo.onload = function(){
canvas.height = photo.height;
...
}
...
reader.onload = function(){
// this will eventually trigger the image's onload event
photo.src = this.result;
}
但是,如果您只需要在画布上绘制图像,甚至不使用FileReader,实际上,readAsDataURL()
方法会在您的大脑中触发I'm doing something wrong
错误。几乎所有你可以使用一个blob的dataURI版本,你也可以使用Blob本身,不用计算它也不会污染浏览器的内存。
例如,要显示用户输入的图像,可以使用URL.createObjectURL(blob)
方法。
// setup the canvas
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// grab the photo and display in canvas
var photo = new Image();
// drawing operations should be in the mage's load event
photo.onload = function() {
// if you don't need to display this image elsewhere
URL.revokeObjectURL(this.src);
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
}
photo.onerror = function(e) {
console.warn('file format not recognised as a supported image');
}
file_input.onchange = function() {
// prefer 'this' over DOM selection
var file = this.files[0];
var url = URL.createObjectURL(file);
photo.src = url;
};
&#13;
<canvas id="canvas" width="0" height="0"></canvas>
<h2>Upload a photo </h2>
<input type="file" id="file_input">
<br>
&#13;
对于需要将此文件发送到其服务器的用户,请使用FormData
直接发送Blob。如果您确实需要dataURI版本,请将其转换为服务器端。