如何上传图像到 HTML5画布

我目前正在使用 http://paperjs.org来创建一个 HTML5画布绘图应用程序。我想让用户上传到画布图像。我知道我需要进行登录和注册,但有一个更简单的方法吗?我已经看到了 HTML5的拖放上传。

102898 次浏览

我假设您的意思是,将图像加载到画布中,而不是从画布上传图像。

你最好把这里所有的帆布文章都看一遍 Https://developer.mozilla.org/en-us/docs/web/guide/html/canvas_tutorial/using_images

但是基本上我们需要做的是用 javascript 创建一个图像,并将 image.src = 设置为任何文件位置。在从用户端加载图像的情况下,需要使用 FileSystemAPI。

这里给出了一个简单的例子: http://jsfiddle.net/influenztial/qy7h5/

function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img,0,0);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
<script>
window.onload = function() {
var canvas=document.getElementById(“drawing”); // grabs the canvas element
var context=canvas.getContext(“2d”); // returns the 2d context object
var img=new Image() //creates a variable for a new image


img.src= “images/vft.jpg” // specifies the location of the image
context.drawImage(img,20,20); // draws the image at the specified x and y location
}
</script>

检查 演示

不需要 FileReader * ,最好使用 CreateObjectURL方法,它将直接创建到磁盘上的 File 的符号链接。这将减少内存使用,而且只需要等待一个异步事件(img.onload中的异步事件)会带来额外的好处。

document.getElementById('inp').onchange = function(e) {
var img = new Image();
img.onload = draw;
img.onerror = failed;
img.src = URL.createObjectURL(this.files[0]);
};
function draw() {
var canvas = document.getElementById('canvas');
canvas.width = this.width;
canvas.height = this.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(this, 0,0);
}
function failed() {
console.error("The provided file couldn't be loaded as an Image media");
}
<input type="file" id="inp">
<canvas id="canvas"></canvas>

* IIRC 只有少数版本的 Chrome 支持 FileReader,而不支持 URL.createObejctURL,所以如果你的目标是这些版本,你可能需要 FileReader。.

创建画布可使用的图像的最佳方法是从输入获得的 File 中创建一个 图片位图

这将使用一个优化的路径来生成浏览器渲染图像所需的内容,并将位图数据存储在 GPU 中,允许在需要时快速绘制。

考虑到这是 没错最近的一个特性(Safari 去年才增加了对它的支持) ,您可能需要使用类似 这是我的的填充材料。

document.querySelector("input").oninput = async (evt) => {
try {
const file = evt.target.files[0];
const bitmap = await createImageBitmap(file);
const canvas = document.querySelector("canvas");
canvas.width = bitmap.width;
canvas.height = bitmap.height;
const ctx = canvas.getContext("2d");
ctx.drawImage(bitmap, 0, 0);
}
catch(err) {
console.error(err);
}
};
<!-- createImageBitmap polyfill for old browsers --> <script src="https://cdn.jsdelivr.net/gh/Kaiido/createImageBitmap/dist/createImageBitmap.js"></script>
<input type="file">
<canvas></canvas>

通过@kaiido 修改答案,每次创建一个新的 canvas元素并将其附加到包装器中。当你不知道你需要多少画布的时候很有用。

注意: 没有 new Canvas()构造函数,因此必须使用 createElement()

document.getElementById('inp').onchange = function(e) {
let img = new Image();
img.onload = draw;
img.onerror = failed;
img.src = URL.createObjectURL(this.files[0]);
};


function draw() {
let canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
canvas.width = this.width;
canvas.height = this.height;
ctx.drawImage(this, 0, 0);
document.getElementById('gallery').append(canvas);
}


function failed() {
console.error("The provided file couldn't be loaded as an Image media");
}
/* entirely decorative */


#gallery {
display: flex;
gap: 1em;
margin: 1em;
}


#gallery canvas {
height: 100px;
border-radius: .5em;
aspect-ratio: 1/1;
object-fit: cover;
}
<input type="file" id="inp">
<div id='gallery'></div>