Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add image as frame to a gif

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.
    }
});
like image 423
nonerth Avatar asked Mar 23 '17 08:03

nonerth


1 Answers

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.

like image 105
mihai Avatar answered Oct 02 '22 17:10

mihai