Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Fisheye for GIF #1489

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
102 changes: 63 additions & 39 deletions src/modules/FisheyeGl/Module.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,53 +11,77 @@ module.exports = function DoNothing(options, UI) {

var step = this;

if (!options.inBrowser) {
require('../_nomodule/gl-context')(input, callback, step, options);
}
else {
// Create a canvas, if it doesn't already exist.
if (!document.querySelector('#image-sequencer-canvas')) {
var canvas = document.createElement('canvas');
canvas.style.display = 'none';
canvas.setAttribute('id', 'image-sequencer-canvas');
document.body.append(canvas);

function extraManipulation(pixels) {
if (!options.inBrowser) {
require('../_nomodule/gl-context')(input, callback, step, options);
}
else var canvas = document.querySelector('#image-sequencer-canvas');

distorter = FisheyeGl({
selector: '#image-sequencer-canvas'
});

// Parse the inputs
options.a = parseFloat(options.a) || distorter.lens.a;
options.b = parseFloat(options.b) || distorter.lens.b;
options.Fx = parseFloat(options.Fx) || distorter.lens.Fx;
options.Fy = parseFloat(options.Fy) || distorter.lens.Fy;
options.scale = parseFloat(options.scale) || distorter.lens.scale;
options.x = parseFloat(options.x) || distorter.fov.x;
options.y = parseFloat(options.y) || distorter.fov.y;
else {
// Create a canvas, if it doesn't already exist.
if (!document.querySelector('#image-sequencer-canvas')) {
var canvas = document.createElement('canvas');
canvas.style.display = 'none';
canvas.setAttribute('id', 'image-sequencer-canvas');
document.body.append(canvas);
}
else var canvas = document.querySelector('#image-sequencer-canvas');

// Set fisheyegl inputs
distorter.lens.a = options.a;
distorter.lens.b = options.b;
distorter.lens.Fx = options.Fx;
distorter.lens.Fy = options.Fy;
distorter.lens.scale = options.scale;
distorter.fov.x = options.x;
distorter.fov.y = options.y;
var distorter = FisheyeGl({
selector: '#image-sequencer-canvas'
});

// generate fisheyegl output
distorter.setImage(input.src, function() {
// Parse the inputs
options.a = parseFloat(options.a) || distorter.lens.a;
options.b = parseFloat(options.b) || distorter.lens.b;
options.Fx = parseFloat(options.Fx) || distorter.lens.Fx;
options.Fy = parseFloat(options.Fy) || distorter.lens.Fy;
options.scale = parseFloat(options.scale) || distorter.lens.scale;
options.x = parseFloat(options.x) || distorter.fov.x;
options.y = parseFloat(options.y) || distorter.fov.y;

// this output is accessible to Image Sequencer
step.output = { src: canvas.toDataURL(), format: input.format };

// Tell Image Sequencer and UI that step has been drawn
callback();
// Set fisheyegl inputs
distorter.lens.a = options.a;
distorter.lens.b = options.b;
distorter.lens.Fx = options.Fx;
distorter.lens.Fy = options.Fy;
distorter.lens.scale = options.scale;
distorter.fov.x = options.x;
distorter.fov.y = options.y;
}

var canvas2 = document.createElement('canvas');
canvas2.width = pixels.shape[0]; //img.width();
canvas2.height = pixels.shape[1]; //img.height();
var ctx2 = canvas2.getContext('2d');

ctx2.putImageData(new ImageData(new Uint8ClampedArray(pixels.data), pixels.shape[0], pixels.shape[1]), 0, 0);
var url1 = canvas2.toDataURL();


distorter.setImage(url1, function() {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is called first time after extramanipulation is called for all frames of gifs. Is there any way to call this synchronously with each frame as the extramanipulation is called.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't get you. Could you please elaborate? Awesome work btw!

Copy link
Author

@ataata107 ataata107 Jan 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks
The only problem is that I want setImage method to be called each time extraManipulation is called i.e the no. of frames in the GIF. But right now the setImage method is called for the first time after the execution of extramanipulation for all the frames are done. Some kind of callback or any way of nesting extramanipulation inside setImage will solve this problem i guess

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll check. Wait a min.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I checked. It is supposed to fire once for every frame.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw the AddQR module which kind of uses similar callbacks but is able to put QR on each frame. Maybe that can help. I am working on it.


var ctx= canvas.getContext('2d');
var myImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
pixels.data = new Uint8Array(myImageData.data);

return pixels;
});
}

function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
}

return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm:options.useWasm
});
}

return {
Expand Down