如何将HTML <canvas> 数据发送到服务器

5
似乎有两种方法可以将<canvas>数据发送到服务器。其中一种是使用canvas.getImageData()获取像素及其8位颜色值的数组。另一种方法是使用canvas.toDataURL()发送文件附件。这种方法在这里演示。

我想建立一个网站,让人们保存他们的画布绘图。哪种方法对我的用户来说更具可扩展性和更快?

3个回答

5

要打开选项:使用fabric.js,您可以将fabric.js画布序列化为JSON。

它不仅提供了额外的编辑功能层,还允许您执行以下操作(更不用说以后能够编辑他们的图像):

var canvas = new fabric.Canvas('c');
canvas.add(
    new fabric.Rect({ top: 100, left: 100, width: 50, height: 50, fill: '#f55' }),
    new fabric.Circle({ top: 140, left: 230, radius: 75, fill: 'green' }),
    new fabric.Triangle({ top: 300, left: 210, width: 100, height: 100, fill: 'blue' })
);

现在,当您想要序列化此画布时,只需调用JSON.stringify函数即可对织物画布对象进行序列化;

JSON.stringify(canvas);

这将为我们上面的示例提供以下类似的结果:

{
    "objects": [
        {
            "type": "rect",
            "left": 100,
            "top": 100,
            "width": 50,
            "height": 50,
            "fill": "#f55",
            "overlayFill": null,
            "stroke": null,
            "strokeWidth": 1,
            "scaleX": 1,
            "scaleY": 1,
            "angle": 0,
            "flipX": false,
            "flipY": false,
            "opacity": 1,
            "selectable": true
        },
        ...
    ]
}

将画布反序列化回其状态的方法是使用:
var canvas = new fabric.Canvas('c');
canvas.loadFromJSON(yourJSONString);

一些额外的资源:

厨房水槽演示 - 查看fabric.js的功能(包括自由绘制;之后修改自由绘制的大小和位置)

主页


如果我允许用户使用标记或笔工具“涂鸦”,这种方法是否有效?我想JSON数组必须很大才能包含所有数据。在这种情况下,您推荐哪种方法更具可扩展性/效率? - Ben G
这取决于您是否需要在以后编辑“涂鸦”,如果是的话,那么它可能完全适合您的需求;如果不需要,则静态图像很可能更好。我会在明天运行一些测试并回复您。 ;) - cillierscharl
太棒了。人们将能够返回并编辑他们的图像。我认为实际的PNG格式比JSON更有效,但也许我错了。 - Ben G
@babonk 一个相对简单的涂鸦大约有600行的JSON代码。对于形状来说,它要少得多。如果您需要稍后编辑涂鸦,我不知道有什么不同于使用此方法的方式。如果您不需要编辑图像,则PNG格式可能更适合您。希望能对您有所帮助 :) - cillierscharl
我明白了。也许有一种方法可以实现它(通过在加载PNG后读取像素数据),但是对于稍后进行编辑的情况,JSON方法似乎更容易。授予您答案。同时,感谢您指出Fabric。 - Ben G

4

您可以.toDataURL()

var datastring = document.getElementById('mycanvas').toDataURL("image/png"));

或使用jQuery

var datastring = $('#mycanvas')[0].toDataURL("image/png");

然后通过XHR将该字符串发送到服务器,这应该是最快的方法。

4
我认为你不能直接从jQuery元素中访问toDataURL。使用$('#mycanvas')[0].toDataURL()来获取相应的DOM节点。 - Boldewyn
1
谢谢。当后期编辑不需要时,这种方法绝对有效。 - Ben G

3
尝试这个方法,在相同情况下它对我有效:

使用JSON.stringify(canvas);获取整个画布的JSON数据。

要从JSON重新加载,请使用以下代码:

canvas.clear();
canvas.loadFromJSON(json_string,canvas.renderAll.bind(canvas));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接