JavaScript 根据数据库中存储的图像数据在画布上绘制图像

问题描述 投票:0回答:1

我正在使用 HTML 和 JS 创建一个持久白板应用程序,用户在 cnavas 上的画布上绘图,单击“保存”,将画布图像数据存储到 mysql 数据库。当页面重新加载时,画布应该从数据库中获取存储的图像数据,并将其重新绘制在画布上,创建持久的白板。

获取函数工作正常,图像数据被正确检索并存储在数据结构中,但是当我重新加载页面时,图像不会被绘制回画布上。具体来说,当我使用

imageData.data.set(最新绘图)

imageData的长度与预期的latestDrawing的长度不匹配,我认为这是问题的原因;有谁知道如何使用预先存在的数据创建新的图像数据?

WhiteBoard.js 中的保存和重绘功能:

window.addEventListener('load', () => {
    resize();
    redraw();

    window.addEventListener('click', handleOutsideClick);
    document.addEventListener("mousedown", startdrawing);
    document.addEventListener("mousemove", sketch);
    document.addEventListener("mouseup", stopdrawing);
    document.addEventListener("mouseout", stopdrawing);
    window.addEventListener('resize', resize);

});


async function saveState() {
    // console.log("before save")

    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

    await fetch('/WhiteBoard', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ type: 'canvasState', data: imageData }),
    });

    console.log("saved")

}

async function redraw() {

    try {
        const response = await fetch('/WhiteBoard');

        var latestDrawing = await response.json();

        if (latestDrawing) {

            //get db data into readable image data form
            latestDrawing = JSON.parse(latestDrawing.data);
            //create a new blank image data
            var imageData = ctx.createImageData(canvas.width, canvas.height);
            imageData.data.set(latestDrawing);
            ctx.putImageData(imageData, 0, 0);
        }

    } catch (error) {
        console.error('Error:', error);
    }

}

Server.js 中的 fetch 函数:

app.get('/WhiteBoard', (req,res) => {
  // Set the content type to JSON
  res.setHeader('Content-Type', 'application/json');
  
  // Your existing query and response logic
  db.query('SELECT * FROM canvas_state ORDER BY id DESC LIMIT 1', (error, results) => {
    if (error) {
      console.error(error);
      res.status(500).send('Internal Server Error');
    } else {
      res.json(results[0]);
    }
  });
});

我尝试创建一个新的 Uint8ClampedArray,因为我阅读了另一篇建议这样做的文章,但是画布仍然没有重新绘制保存的图像

const dataArray = new Uint8ClampedArray(drawingData);
javascript html5-canvas
1个回答
0
投票

我认为后端与这里无关。一旦您可以通过

JSON.stringify()
传递数据,那么您就将问题隔离到了前端。

这是一种在一个画布上绘制内容、通过 JSON 字符串传递数据并将其写入另一个画布的方法:

const serializeCanvas = canvas => {
  const ctx = canvasA.getContext("2d");
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  const {buffer} = imageData.data;
  const dataArray = Array.from(new Uint8ClampedArray(buffer));
  return JSON.stringify(dataArray);
};

const writeCanvas = (canvas, data) => {
  const ctx = canvas.getContext("2d");
  const imageData = ctx.createImageData(canvas.width, canvas.height);
  imageData.data.set(data);
  ctx.putImageData(imageData, 0, 0);
};

const [canvasA, canvasB] = document.querySelectorAll("canvas");

// draw a square
canvasA.getContext("2d").fillRect(10, 10, 20, 20);
const json = serializeCanvas(canvasA);

// store `json` to the backend ...

// ... later on, restore it from a response:
writeCanvas(canvasB, JSON.parse(json));
canvas {
  border: 1px solid black;
}
<canvas></canvas>
<canvas></canvas>

© www.soinside.com 2019 - 2024. All rights reserved.