保存手绘图中的数据(不是图像文件)

Posted

技术标签:

【中文标题】保存手绘图中的数据(不是图像文件)【英文标题】:Save Data from Freehand Drawing (not as an image file) 【发布时间】:2015-06-05 04:59:28 【问题描述】:

我一直在尝试从 html5 Canvas 的绘图功能中保存数据/对象,我将如何通过 x 和 y 坐标点将其保存到 mysql 表中,而不是将其转换为 JPEG 或图像文件?。

目标是将笔画保存为数据文件而不是图像文件。我该怎么做?

var canvas = document.getElementById('canvas'),
    coord = document.getElementById('coord'),
    ctx = canvas.getContext('2d'), // get 2D context
    imgCat = new Image();

  /*********** draw image *************/
  imgCat.src = 'http://c.wearehugh.com/dih5/openclipart.org_media_files_johnny_automatic_1360.png';
  imgCat.onload = function()  // wait for image load
    ctx.drawImage(imgCat, 0, 0); // draw imgCat on (0, 0)
  ;

  /*********** handle mouse events on canvas **************/
  var mousedown = false;
  ctx.strokeStyle = '#0000FF';
  ctx.lineWidth = 2;
  canvas.onmousedown = function(e) 
    var pos = fixPosition(e, canvas);
    mousedown = true;
    ctx.beginPath();
    ctx.moveTo(pos.x, pos.y);
    return false;
  ;

  canvas.onmousemove = function(e) 
    var pos = fixPosition(e, canvas);
    coord.innerHTML = '(' + pos.x + ',' + pos.y + ')';
    if (mousedown) 
      ctx.lineTo(pos.x, pos.y);
      ctx.stroke();
    
  ;

  canvas.onmouseup = function(e) 
    mousedown = false;
  ;

  /********** utils ******************/
  // Thanks to http://***.com/questions/55677/how-do-i-get-the-coordinates-of-a-mouse-click-on-a-canvas-element/4430498#4430498
  function fixPosition(e, gCanvasElement) 
    var x;
    var y;
    if (e.pageX || e.pageY) 
      x = e.pageX;
      y = e.pageY;
     else 
      x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
      y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    
    x -= gCanvasElement.offsetLeft;
    y -= gCanvasElement.offsetTop;
    return 
      x: x,
      y: y
    ;
  
  ``
<div id="left_col">
  <canvas id="canvas"   style='background-image:url(http://www.robertshadbolt.com/content/01-articles/01-900x900/900x900.gif);' center cetner no-repeat></canvas>
  <div id="coord" hidden></div>

Fiddle

【问题讨论】:

您可以使用 canvas.toDataURL() 将画布返回的数据直接保存到您的数据库中:) @AkshayJ 会将画布保存为图像,这是 OP 想要避免的。该字符串包含编码为 base-64 的二进制图像,而不是矢量点 是的...K3N 得到你 nw :) 【参考方案1】:

Canvas 无法处理矢量图形,因为它会光栅化任何绘制到它的东西。因此画布只会为您提供位图(原始或编码为图像)。画布只能显示这些矢量被光栅化的结果,但以后永远不能以原始形式提供它们。

要获得处理向量的效果,需要做到以下几点:

以可序列化的格式(例如带有文字对象的数组)跟踪和收集点。换句话说:您需要在鼠标处理程序中“记录”这些点,同时将它们渲染到画布上。

您还需要分离“笔画”(笔画是从鼠标向下到鼠标向上,然后为下一个笔画创建一个新数组等。这意味着您将需要一个具有两个级别的对象,一个用于收集笔画数组,每个笔划一个数组)。

完成后,您可以使用 JSON.stringify() 序列化数组并发送到您的数据库。

要恢复,请读回该字符串并使用 JSON.parse() 恢复数组。

简化示例

// some dummy point in a serializeable format:
var points = [
      x: 10, y: 10,
      x: 20, y: 50,
      x: 100, y: 10
    ];

// serialize
var str = JSON.stringify(points);
document.write("To server: " + str + "<br>");

// send str to database here...

// RESTORE

// read from database here

var restoredPoints = JSON.parse(str);
document.write("Point from restored array - x: " +
               restoredPoints[1].x + " y: " +
               restoredPoints[1].y);

在一个更真实的例子中,您的对象看起来像(伪代码):

var strokes = [];

onmousedown: 
   create new array -> strokes.push([]);
   index = strokes.length - 1;
   add point to current stroke -> strokes[index].push(x:x, y:y);

onmousemove:
   add point to current stroke -> strokes[index].push(x:x, y:y);

【讨论】:

@K3N 你怎么能从画布上获取这些点??后面的部分是同意的。 @AkshayJ 记录他们 哈哈...有点乏味,但我想它会起作用的 :) 干杯 @AkshayJ 这实际上是从画布保存矢量的唯一方法(从技术上讲,画布不涉及,因为它只处理位图,但它会呈现您要记录和保存的点) yeah :)canvas 基本上是用来处理位图的

以上是关于保存手绘图中的数据(不是图像文件)的主要内容,如果未能解决你的问题,请参考以下文章

数据分析与展示--图像的手绘效果(实例)

将点击的图像保存到自定义文件夹(最好是应用程序内部)而不是图库

Android:如何保存不是(JPEG 和 PNG)的图像文件? [旋转后]

将图像保存在公共文件夹中,而不是存储 laravel 5

将 JPanel 保存为图像(不是文件,而是变量)

C++如何把位图保存到数组中