nodejs - 如何将文件中的图像数据添加到画布中

mes*_*esh 14 canvas image node.js html5-canvas

以下代码应该读取图像文件,然后在Canvas模块的帮助下将文件数据添加到画布中.

当我运行此代码时,我收到错误消息图像未定义.我试图从我简单导入的模块初始化的图像对象是什么?

var http = require('http'), fs = require('fs'), 
Canvas = require('canvas');

http.createServer(function (req, res) {
    fs.readFile(__dirname + '/image.jpg', function(err, data) {
        if (err) throw err;
        img = new Image();
        img.src = data;
        ctx.drawImage(img, 0, 0, img.width / 4, img.height / 4);

        res.write('<html><body>');
        res.write('<img src="' + canvas.toDataURL() + '" />');
        res.write('</body></html>');
        res.end();
    });

}).listen(8124, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8124/');
Run Code Online (Sandbox Code Playgroud)

Roh*_*ngh 40

如果我在这里错了,我很抱歉,但看起来你已经在某个地方发现了这个代码并尝试使用它而没有真正理解封面下发生的事情.即使您要修复Image未定义的错误,也有很多其他错误.

我在本文末尾有固定的代码,但我建议您在问题的代码中更深入地思考这些问题:

  • 什么是Image?它从何而来?你进口http,fsCanvas,所以这些事情显然定义.但是,Image没有在任何地方定义,它不是内置的.

    事实证明,Image是来自您导入的node-canvas模块Canvas = require('canvas').这意味着Image可用Canvas.Image.

    重要的是要了解这是因为你已经设置了导入.你可以轻松完成abc = require('canvas'),然后Image就可以使用abc.Image.

  • 什么是ctx?它来自哪里?

    同样,这是另一个尚未在任何地方定义的变量.不像Image,它不可用Canvas.ctx.它只是一个随机变量名,在这一点上与任何东西都不对应,所以试图调用drawImage它会抛出异常.

  • 怎么样canvas(小写)?那是什么?

    你正在使用canvas.toDataURL,但没有任何变量canvas.你期望这段代码做什么?现在它只是抛出一个异常,说画布未定义.

我建议您更仔细地阅读文档,并仔细查看将来复制到您自己的应用程序中的任何示例代码.


这是固定代码,有一些注释来解释我的更改.我通过快速查看https://github.com/learnboost/node-canvas上的文档来解决这个问题.

var http = require('http'), fs = require('fs'), 
Canvas = require('canvas');

http.createServer(function (req, res) {
    fs.readFile(__dirname + '/image.jpg', function(err, data) {
        if (err) throw err;
        var img = new Canvas.Image; // Create a new Image
        img.src = data;

        // Initialiaze a new Canvas with the same dimensions
        // as the image, and get a 2D drawing context for it.
        var canvas = new Canvas(img.width, img.height);
        var ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0, img.width / 4, img.height / 4);

        res.write('<html><body>');
        res.write('<img src="' + canvas.toDataURL() + '" />');
        res.write('</body></html>');
        res.end();
    });

}).listen(8124, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8124/');
Run Code Online (Sandbox Code Playgroud)

  • 是的,那里有懒惰的文档。只需在节点画布模块代码本身的上下文中使用“Image”就可以了,因为它在其源代码(lib/canvas.js)中定义了“Image = canvas.Image”。但是,除非您做出相同的定义,否则它在您自己的代码中不起作用。 (2认同)
  • @RohanSingh,我们不需要等待`ImageObj.onload`吗? (2认同)

aen*_*rew 5

node-canvas 现在有一个辅助函数 ,loadImage它返回一个解析为加载对象的 Promise Imageonload这可以防止像已接受的答案那样与处理程序混淆。

const http = require('http'); 
const fs = require('fs');
const Canvas = require('canvas');

http.createServer(function (req, res) {
    fs.readFile(__dirname + '/image.jpg', async function(err, data) {
        if (err) throw err;
        const img = await Canvas.loadImage(data);
        const canvas = new Canvas(img.width, img.height);
        const ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0, img.width / 4, img.height / 4);

        res.write('<html><body>');
        res.write('<img src="' + canvas.toDataURL() + '" />');
        res.write('</body></html>');
        res.end();
    });

}).listen(8124, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8124/');
Run Code Online (Sandbox Code Playgroud)