将图像作为帧添加到gif动画中

9

我想创建一个gif并添加一张图片作为帧。我正在使用gifencoder。我已经看过了示例,添加颜色、文本等非常容易,但我无法弄清如何添加图像。我需要像png文件流这样的东西吗?

例如:从网站获取颜色框架。

let canvas = new Canvas(width, height);
var ctx = canvas.getContext('2d');
red rectangle
ctx.fillStyle = '#ff0000';
ctx.fillRect(0, 0, 320, 240);
encoder.addFrame(ctx);

编辑:

我尝试过像下面这样做,虽然框架出现在我的日志中,但框架没有被添加,也没有错误。在有人建议将png/gif转换为base64之前,该模块无法添加这样的框架。话虽如此,如果您知道其他可以实现此功能的模块,请继续分享。

fs.createReadStream('test.gif')
.pipe(new GIFDecoder) //gif-stream
.pipe(concat(function(frames) { //concat-frames
    console.log(frames);
    for (var i=0; i<frames.length; i++) {
        encoder.addFrame(frames[i]);
    }
}));

无论我尝试什么,最多只会得到一个黑色的gif,没有其他内容。

编辑2:

好吧,我之所以试图从gif中添加帧,是因为它看起来更容易。下面是我尝试获取图片、将其转换为RGBA格式(我注意到该模块接受rgba格式而不是rgb,可能这就是它总是黑色的原因),然后添加帧的进展情况。如果我有数据,添加帧非常容易,因为我只需调用一个方法并将数据推入其中,所以我将留下那部分内容。

var request = require('request').defaults({ encoding: null });

request.get('https://upload.wikimedia.org/wikipedia/commons/0/01/Quinlingpandabearr.jpg', function (error, response, body) {
    if (!error && response.statusCode == 200) {
        var img = new Canvas(105, 159);        
        var context = img.getContext('2d');
        img.src = "data:" + response.headers["content-type"] + ";base64," + new Buffer(body).toString('base64');
        var img_to_rgba = context.getImageData(0, 0, img.width, img.height);
        console.log(img_to_rgba); //always returns 0, like my pic is completely black, its not.
    }
});

1
嗯,有人有任何想法吗? - nonerth
那么这个问题解决了吗(在编辑2之后它正常工作了)? - VC.One
是的,抱歉我正在忙于某事,我会在答案中回复。 - nonerth
没关系,我只是路过,有点困惑这个问题是否解决了。不管怎样,这是一个有趣的想法。 - VC.One
2个回答

6

我已经在gif图像旁边添加了一个帧,以及一个蓝色的正方形。

下面是完整的代码,已测试并运行良好:

var GIFEncoder = require('gifencoder');
var Canvas = require('canvas');
var fs = require('fs');

var encoder = new GIFEncoder(320, 240);

encoder.createReadStream().pipe(fs.createWriteStream('myanimated.gif'));

encoder.start();
encoder.setRepeat(0);   
encoder.setDelay(500);  
encoder.setQuality(10); 

var canvas = new Canvas(320, 240);
var ctx = canvas.getContext('2d');

// blue rectangle frame
ctx.fillStyle = '#0000ff';
ctx.fillRect(0, 0, 320, 240);
encoder.addFrame(ctx);

// image frame
var data = fs.readFileSync(__dirname + '/image.jpg');
var img = new Canvas.Image; 
img.src = data;
ctx.drawImage(img, 0, 0, 320, 240);
encoder.addFrame(ctx);

encoder.finish();

请注意,这次我使用的是readFileSync,但你也可以根据你的代码像我其他的答案一样使用readFile。我还改变了加载图像的尺寸,以适应正方形。

确实有效,尽管我的第二次编辑也有效。我会接受这个答案,因为它符合问题的标准并且很清晰。关于你的另一个答案,它与将图像添加到gif中没有什么关系,而更像是读取图像。 - nonerth
你只需要一行代码... encoder.addFrame(ctx); - mihai
在那个时间我没有使用 gifencoder 而是使用了 gif-encoder,除非我错了,否则需要 RGBA 数据,所以你可以只做 encoder.addFrame(ctx);,不过现在已经没关系了,毕竟你可以清楚地看到我在第一段发布的代码片段中尝试过这样做。 - nonerth
我会坦诚地说,既然我已经解决了这个问题,我不认为这个答案值得获得赏金,但是为了更好地指导未来的谷歌搜索者,并为你的双倍努力奖励你 - 我听起来像个刻薄的人,但我希望不是这样。 - nonerth

-3

你可以使用fs.readFile将图像加载到画布上:

fs.readFile(__dirname + '/image.jpg', function(err, data) {
    if (err) throw err;
    var img = new canvas.Image; 
    img.src = data;
    ctx.drawImage(img, 0, 0, img.width, img.height);
})

2
很抱歉,也许我没有解释清楚,但那不是我要问的,正如我所说,“添加颜色”非常容易,我想要添加整个图像,我知道如何添加完全红色或任何其他颜色的边框。假设我有一个名为“image.jpg”的图像,那么我希望我的gif的第一帧是那个“image.jpg”。 - nonerth
抱歉...请看我的新回答。 - mihai
请注意,在使用gifencoder后,当我执行encoder.addFrame(ctx);时。 - nonerth
1
这不是原帖所问的内容。 - We're All Mad Here
如果您有任何链接,能否请提供一下?我并不是在寻求别人的帮助,但这并不是我所问的问题,尽管我很感激@mihai的努力。 - nonerth
显示剩余4条评论

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