mirror of
https://github.com/publiclab/image-sequencer.git
synced 2025-12-08 17:30:01 +01:00
* add canvas resize module Signed-off-by: tech4GT <varun.gupta1798@gmail.com> * add tests Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
101 lines
3.0 KiB
JavaScript
101 lines
3.0 KiB
JavaScript
/*
|
|
* General purpose per-pixel manipulation
|
|
* accepting a changePixel() method to remix a pixel's channels
|
|
*/
|
|
module.exports = function PixelManipulation(image, options) {
|
|
|
|
// To handle the case where pixelmanipulation is called on the input object itself
|
|
// like input.pixelManipulation(options)
|
|
if (arguments.length <= 1) {
|
|
options = image;
|
|
image = this;
|
|
}
|
|
|
|
options = options || {};
|
|
|
|
const getPixels = require("get-pixels"),
|
|
savePixels = require("save-pixels");
|
|
|
|
getPixels(image.src, function(err, pixels) {
|
|
if (err) {
|
|
console.log("Bad image path", image);
|
|
return;
|
|
}
|
|
|
|
if (options.getNeighbourPixel) {
|
|
options.getNeighbourPixel.fun = function getNeighborPixel(distX, distY) {
|
|
return options.getNeighbourPixel(pixels, x, y, distX, distY);
|
|
};
|
|
}
|
|
|
|
// iterate through pixels;
|
|
// TODO: this could possibly be more efficient; see
|
|
// https://github.com/p-v-o-s/infragram-js/blob/master/public/infragram.js#L173-L181
|
|
|
|
if (!options.inBrowser && !process.env.TEST) {
|
|
try {
|
|
var pace = require("pace")(pixels.shape[0] * pixels.shape[1]);
|
|
} catch (e) {
|
|
options.inBrowser = true;
|
|
}
|
|
}
|
|
|
|
if (options.preProcess) pixels = options.preProcess(pixels); // Allow for preprocessing
|
|
|
|
if (options.changePixel) {
|
|
|
|
/* Allows for Flexibility
|
|
if per pixel manipulation is not required */
|
|
|
|
for (var x = 0; x < pixels.shape[0]; x++) {
|
|
for (var y = 0; y < pixels.shape[1]; y++) {
|
|
let pixel = options.changePixel(
|
|
pixels.get(x, y, 0),
|
|
pixels.get(x, y, 1),
|
|
pixels.get(x, y, 2),
|
|
pixels.get(x, y, 3),
|
|
x,
|
|
y
|
|
);
|
|
|
|
pixels.set(x, y, 0, pixel[0]);
|
|
pixels.set(x, y, 1, pixel[1]);
|
|
pixels.set(x, y, 2, pixel[2]);
|
|
pixels.set(x, y, 3, pixel[3]);
|
|
|
|
if (!options.inBrowser && !process.env.TEST) pace.op();
|
|
}
|
|
}
|
|
}
|
|
// perform any extra operations on the entire array:
|
|
var res;
|
|
if (options.extraManipulation) res = options.extraManipulation(pixels, generateOutput);
|
|
// there may be a more efficient means to encode an image object,
|
|
// but node modules and their documentation are essentially arcane on this point
|
|
function generateOutput() {
|
|
var chunks = [];
|
|
var totalLength = 0;
|
|
|
|
var r = savePixels(pixels, options.format, { quality: 100 });
|
|
|
|
r.on("data", function(chunk) {
|
|
totalLength += chunk.length;
|
|
chunks.push(chunk);
|
|
});
|
|
|
|
r.on("end", function() {
|
|
var data = Buffer.concat(chunks, totalLength).toString("base64");
|
|
var datauri = "data:image/" + options.format + ";base64," + data;
|
|
if (options.output)
|
|
options.output(options.image, datauri, options.format);
|
|
if (options.callback) options.callback();
|
|
});
|
|
}
|
|
if (res) {
|
|
pixels = res;
|
|
generateOutput();
|
|
}
|
|
else if (!options.extraManipulation) generateOutput();
|
|
});
|
|
};
|