【问题标题】:Node.js Canvas image overlapping issue / canvas is creating image on top of previous imageNode.js 画布图像重叠问题/画布正在上一个图像之上创建图像
【发布时间】:2022-01-04 04:43:45
【问题描述】:

我在尝试创建生成的 .png 图像集合时遇到了 Canvas 问题。 我可以很好地创建 .png 文件,但第一个图像或之前的图像没有被清除。

index.js

const fs = require("fs");
const { createCanvas, loadImage } = require("canvas");
const canvas = createCanvas(1000,1000);
const ctx = canvas.getContext("2d");
const edition = 10;
const {layers,width,height} = require("./input/config.js");

const saveLayer = (_canvas, _edition) => {
    fs.writeFileSync(`./output/${_edition}.png`, _canvas.toBuffer("image/png"));
};

const drawLayer = async (_layer, _edition) => {
    let element = _layer.elements[Math.floor(Math.random() * _layer.elements.length)];
    const image = await loadImage(`${_layer.location}${element.fileName}`);
    ctx.drawImage(
        image, 
        _layer.position.x,
         _layer.position.y, 
         _layer.size.width, 
         _layer.size.height
         );
    console.log(`I created the ${_layer.name} layer, and chose element ${element.name}`);
    saveLayer(canvas, _edition);
};


for(let i = 0; i <= edition; i++){
    
    layers.forEach(layer => {
        drawLayer(layer, i);    
    });
  console.log("Creating edition " + i);
};

config.js

const fs = require("fs");
const width  = 1000;
const height = 1000;

const dir = __dirname;

const rarity = [
    {key: "", val: "original" },
    {key: "_r", val: "rare" },
    {key: "_sr", val: "super rare" },
];

const addRarity = (_str) => {
    let itemRarity;
    rarity.forEach((r) => {
        if (_str.includes(r.key)){
            itemRarity = r.val;
        }
    });
    return itemRarity;
};

const cleanName = (_str) => {
    let name = _str.slice(0, -4);

    return name;
};
const getElements = (path) => {
    return fs
    .readdirSync(path)
    //.filter((item) => !/(^|\/)\.|^\/\.|/g.test(item))
    .map((i,index) => {
        return {
            id: index,
            name: cleanName(i),
            fileName: i,
            rarity: addRarity(i),
        };
    });
};

const layers = [
    {
    id: 1,
    name: "0",
    location: `${dir}/0/`,
    elements: getElements(`${dir}/0/`),
    position: {x:0, y:0},
    size: {width: width, height: height},
},
{
    id: 2,
    name: "1",
    location: `${dir}/1/`,
    elements: getElements(`${dir}/1/`),
    position: {x:0, y:0},
    size: {width: width, height: height},
},
{
    id: 3,
    name: "2",
    location: `${dir}/2/`,
    elements: getElements(`${dir}/2/`),
    position: {x:0, y:0},
    size: {width: width, height: height},
},
{
    id: 4,
    name: "3",
    location: `${dir}/3/`,
    elements: getElements(`${dir}/3/`),
    position: {x:0, y:0},
    size: {width: width, height: height},
},
{
    id: 5,
    name: "4",
    location: `${dir}/4/`,
    elements: getElements(`${dir}/4/`),
    position: {x:0, y:0},
    size: {width: width, height: height},
},
];

//console.log(layers);
module.exports = {layers,width,height};

代码运行良好,我可以创建 10 个 .png 文件。

从上面的图片中,您可以看到图片 1 中的蓝色帽子仍然显示在图片 2 中。

编辑:我尝试过的 -

   ctx.beginPath();
   context.clearRect(0, 0, canvas.width, canvas.height);


const createNFTs = async() =>{

    for(let i = 1; i <= edition; i++){

        for (const layer of layers) await drawLayer(layer, i);
        console.log("Creating edition " + i);
    
    };
};

最终代码:

 for(let i = 1; i <= edition; i++){
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        for (const layer of layers) await drawLayer(layer, i);
        console.log("Creating edition " + i);
    
    };

【问题讨论】:

    标签: javascript node.js canvas generative-art


    【解决方案1】:

    你有一个 forEach 调用异步函数。

    forEach 和 async 不能一起使用:forEach 在前一个图像完成之前绘制下一个图像

    替换

    layers.forEach(layer => {
        drawLayer(layer, i);    
    });
    

    for (const layer of layers) {
        await drawLayer(layer, i);
        ctx.clearRect(0, 0, canvas.width, canvas.height);
    }
    

    (添加清除) 并将其放入异步函数中

    【讨论】:

    • 感谢您的回复。上面的代码正在运行并生成 10 个 .png 图像,但我遇到了同样的问题,我调用异步函数的方式有问题吗?编辑中的代码,
    • for 循环内是否有透明画布?查看更新的答案
    • 太棒了!它现在按预期工作,并且正在清除以前的图像。非常感谢!我能够通过..(在编辑中)解决问题。
    猜你喜欢
    • 1970-01-01
    • 2016-11-18
    • 2011-09-05
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 2013-08-25
    • 1970-01-01
    相关资源
    最近更新 更多