Add image as frame to a gif
Asked Answered
B

2

9

So I want to create a gif and add an image as a frame. I am using gifencoder. I've seen the examples and its pretty easy to add colors, txt etc, but I couldnt figure out how to do the same with an image. Do I need something like the png file stream.

ex: from website for color frame

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);

Edit:

I tried doing something like below and while the frames appear on my log as wanted the frames dont get added, no errors. Before someone suggests to convert to base64 the png/gif this module cant add such frames, that being said if you have another in mind that does please go ahead and say so.

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]);
    }
}));

whatever I have tried at best I get just a black gif, nothing more.

Edit 2:

Okay so the reason I am trying to add from from a gif the frame, was because it simply seemed easier. Below is the progress I have done trying to get an image, convert it to RGBA (i noticed the module accepts rgba format, not rgb, perhaps that's why it was always black) and afterwards add the frame. Adding the frame if I have the data is extremely easy as I simply call a method and push the data in, so I am going to leave that out.

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.
    }
});
Bevash answered 23/3, 2017 at 8:57 Comment(4)
Uhm so does anyone have any ideas?Bevash
So it this solved (after edit 2 it's working fine)?Harrelson
Yes, sorry I was being busy with something, I'll wrap it in an answer perhapsBevash
No rush. I was just passing by and got confused as to whether solved or not. Interesting idea anyways.Harrelson
A
6

I've added an image as a frame to a gif, along side a blue square.

Here is the full code, tested and working fine for me:

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();

Note that I'm using readFileSync this time, but you can use readFile too as in my other answer, depending on your code. I've also change the size of the loaded image, to fit the square.

Aldas answered 31/3, 2017 at 18:28 Comment(4)
Indeed it does work, though my second edit worked as well. I will accept the answer as it does fill the questions criteria and its clear. Regarding your other answer it didnt really had anything to do with adding the image to the gif but more like reading the image.Bevash
you just needed one line of code...encoder.addFrame(ctx);Aldas
I didnt use gifencoder but gif-encoder at the time which unless I am wrong requires rgba data so you can just do encoder.addFrame(ctx);, regardless it doesnt matter now, after all you can clearly see I tried that in the first snippet I had postedBevash
I'll be truthful about it and say, since I already had solved the question I dont think this answer deserves a bounty however in order to guide future googlers better and for your double efforts I'll reward you with it - I sound like a mean guy but am not(hope so).Bevash
A
-3

You can load the image onto the canvas with 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);
})
Aldas answered 23/3, 2017 at 12:15 Comment(9)
I am sorry, perhaps I didnt explain it well but thats not what I am asking, as I said "its pretty easy to add colors", I am looking to add a whole image, I know how to add a fully red or whatever frame. Lets say I have an image named "image.jpg", then I want the first frame to be that "image.jpg" in my gifBevash
sorry for that...see my new answer.Aldas
its okay, though (edit: not thought - typo) that just gives me a black image as a result. btw you might want to change )} -> });Bevash
Let me note that after I do encoder.addFrame(ctx); with the gifencoder.Bevash
yes, definitely...this is just for loading onto the canvas, then you need to add the frame to the encoderAldas
uhm with a for adding the data(I only want one frame though), could please elaborate that, mainly that is my prob not getting the image with fsBevash
thats not what the OP is asking.Bouzoun
...it's the missing link...sorry for not creating a fully copy-pastable example.Aldas
could you please post the link if you have any, I am not looking for spoon feed, but thats really not what I asked, though I appreciate the effort @AldasBevash

© 2022 - 2024 — McMap. All rights reserved.