Ported even more commands to Magick++
This commit is contained in:
parent
950ce00a80
commit
78dbeabd39
24 changed files with 468 additions and 65 deletions
|
@ -5,7 +5,7 @@ exports.run = async (message) => {
|
|||
message.channel.sendTyping();
|
||||
const image = await require("../utils/imagedetect.js")(message);
|
||||
if (image === undefined) return `${message.author.mention}, you need to provide an image to blur!`;
|
||||
const buffer = await promisify(magick.blur)(image.path, image.type.toUpperCase(), image.delay ? (100 / image.delay.split("/")[0]) * image.delay.split("/")[1] : 0);
|
||||
const buffer = await promisify(magick.blur)(image.path, false, image.type.toUpperCase(), image.delay ? (100 / image.delay.split("/")[0]) * image.delay.split("/")[1] : 0);
|
||||
return {
|
||||
file: buffer,
|
||||
name: `blur.${image.type}`
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const gm = require("gm").subClass({
|
||||
imageMagick: true
|
||||
});
|
||||
const magick = require("../build/Release/image.node");
|
||||
const { promisify } = require("util");
|
||||
|
||||
exports.run = async (message, args) => {
|
||||
const image = await require("../utils/imagedetect.js")(message);
|
||||
|
@ -9,26 +8,10 @@ exports.run = async (message, args) => {
|
|||
if (args.length === 0) return `${message.author.mention}, you need to provide some text to make a motivational poster!`;
|
||||
const processMessage = await message.channel.createMessage("<a:processing:479351417102925854> Processing... This might take a while");
|
||||
const [topText, bottomText] = newArgs.join(" ").split(/(?<!\\),/).map(elem => elem.trim());
|
||||
const file = `/tmp/${Math.random().toString(36).substring(2, 15)}.miff`;
|
||||
const text = `/tmp/${Math.random().toString(36).substring(2, 15)}.png`;
|
||||
const text2 = `/tmp/${Math.random().toString(36).substring(2, 15)}.png`;
|
||||
const buffer = await gm().in("(").in(image.path).coalesce().scale(500, 500).borderColor("black").border(5, 5).out(")").borderColor("white").border(3, 3).bufferPromise("miff", image.delay);
|
||||
await gm(buffer).coalesce().background("black").gravity("Center").extent(600, "%[fx:s.h+50]").writePromise(file);
|
||||
const size2 = await gm(file).sizePromise();
|
||||
await gm().background("black").out("-size", "600").fill("white").font("Times").pointSize(56).gravity("Center").out(`pango:${topText.replace(/&/g, "\\&").replace(/>/g, "\\>").replace(/</g, "\\<").replace(/"/g, "\\"").replace(/'/g, "\\'")}`).gravity("South").out("-splice", bottomText ? "0x0" : "0x20").writePromise(text);
|
||||
const size3 = await gm(text).sizePromise();
|
||||
const command2 = gm(file).gravity("North").coalesce().extent(600, size2.height + size3.height).out("null:", "(", text, "-set", "page", `+0+${size2.height}`, ")", "-layers", "composite");
|
||||
let resultBuffer;
|
||||
if (bottomText) {
|
||||
await gm().background("black").out("-size", "600").fill("white").font("Times").pointSize(28).gravity("Center").out(`pango:${bottomText.replace(/&/g, "\\&").replace(/>/g, "\\>").replace(/</g, "\\<").replace(/"/g, "\\"").replace(/'/g, "\\'")}`).gravity("South").out("-splice", "0x20").writePromise(text2);
|
||||
const size4 = await gm(text2).sizePromise();
|
||||
resultBuffer = await gm(await command2.bufferPromise(image.type, image.delay)).gravity("North").coalesce().extent(600, size2.height + size3.height + size4.height).out("null:", "(", text2, "-set", "page", `+0+${size2.height + size3.height}`, ")", "-layers", "composite").bufferPromise(image.type, image.delay);
|
||||
} else {
|
||||
resultBuffer = await command2.bufferPromise(image.type, image.delay);
|
||||
}
|
||||
const buffer = await promisify(magick.motivate)(image.path, topText.replace(/&/g, "\\&").replace(/>/g, "\\>").replace(/</g, "\\<").replace(/"/g, "\\"").replace(/'/g, "\\'"), bottomText ? bottomText.replace(/&/g, "\\&").replace(/>/g, "\\>").replace(/</g, "\\<").replace(/"/g, "\\"").replace(/'/g, "\\'") : "", image.type.toUpperCase(), image.delay ? (100 / image.delay.split("/")[0]) * image.delay.split("/")[1] : 0);
|
||||
processMessage.delete();
|
||||
return {
|
||||
file: resultBuffer,
|
||||
file: buffer,
|
||||
name: `motivate.${image.type}`
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
const gm = require("gm").subClass({
|
||||
imageMagick: true
|
||||
});
|
||||
const magick = require("../build/Release/image.node");
|
||||
const { promisify } = require("util");
|
||||
|
||||
exports.run = async (message) => {
|
||||
message.channel.sendTyping();
|
||||
const image = await require("../utils/imagedetect.js")(message);
|
||||
if (image === undefined) return `${message.author.mention}, you need to provide an image to pixelate!`;
|
||||
const buffer = await gm(image.path).coalesce().scale("10%").coalesce().scale("1000%").bufferPromise(image.type, image.delay);
|
||||
const buffer = await promisify(magick.resize)(image.path, image.type.toUpperCase(), image.delay ? (100 / image.delay.split("/")[0]) * image.delay.split("/")[1] : 0);
|
||||
return {
|
||||
file: buffer,
|
||||
name: `pixelate.${image.type}`
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
const gm = require("gm").subClass({
|
||||
imageMagick: true
|
||||
});
|
||||
const magick = require("../build/Release/image.node");
|
||||
const { promisify } = require("util");
|
||||
|
||||
exports.run = async (message) => {
|
||||
message.channel.sendTyping();
|
||||
const image = await require("../utils/imagedetect.js")(message);
|
||||
if (image === undefined) return `${message.author.mention}, you need to provide a GIF to reverse!`;
|
||||
if (image.type !== "gif") return `${message.author.mention}, that isn't a GIF!`;
|
||||
const buffer = await gm(image.path).coalesce().out("-reverse").bufferPromise(image.type, image.delay);
|
||||
const buffer = await promisify(magick.reverse)(image.path, image.delay ? (100 / image.delay.split("/")[0]) * image.delay.split("/")[1] : 0);
|
||||
return {
|
||||
file: buffer,
|
||||
name: "reverse.gif"
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
const gm = require("gm").subClass({
|
||||
imageMagick: true
|
||||
});
|
||||
const magick = require("../build/Release/image.node");
|
||||
const { promisify } = require("util");
|
||||
|
||||
exports.run = async (message) => {
|
||||
message.channel.sendTyping();
|
||||
const image = await require("../utils/imagedetect.js")(message);
|
||||
if (image === undefined) return `${message.author.mention}, you need to provide an image to make a Scott the Woz TV meme!`;
|
||||
const template = "./assets/images/scott.png";
|
||||
const buffer = await gm(template).out("null:").out("(").out(image.path).coalesce().out("-virtual-pixel", "transparent").resize("415x234!").out("+distort", "Perspective", "0,0 129,187 415,0 517,182 415,234 517,465 0,234 132,418").out(")").compose("over").gravity("Center").geometry("-238-98").out("-layers", "composite").bufferPromise(image.type, image.delay);
|
||||
//const template = "./assets/images/scott.png";
|
||||
//const buffer = await gm(template).out("null:").out("(").out(image.path).coalesce().out("-virtual-pixel", "transparent").resize("415x234!").out("+distort", "Perspective", "0,0 129,187 415,0 517,182 415,234 517,465 0,234 132,418").out(")").compose("over").gravity("Center").geometry("-238-98").out("-layers", "composite").bufferPromise(image.type, image.delay);
|
||||
const buffer = await promisify(magick.scott)(image.path, image.type.toUpperCase(), image.delay ? (100 / image.delay.split("/")[0]) * image.delay.split("/")[1] : 0);
|
||||
return {
|
||||
file: buffer,
|
||||
name: `scott.${image.type}`
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
const gm = require("gm").subClass({
|
||||
imageMagick: true
|
||||
});
|
||||
const magick = require("../build/Release/image.node");
|
||||
const { promisify } = require("util");
|
||||
|
||||
exports.run = async (message) => {
|
||||
message.channel.sendTyping();
|
||||
const image = await require("../utils/imagedetect.js")(message);
|
||||
if (image === undefined) return `${message.author.mention}, you need to provide an image to sharpen!`;
|
||||
const buffer = await gm(image.path).coalesce().sharpen(10, 3).bufferPromise(image.type, image.delay);
|
||||
const buffer = await promisify(magick.blur)(image.path, true, image.type.toUpperCase(), image.delay ? (100 / image.delay.split("/")[0]) * image.delay.split("/")[1] : 0);
|
||||
return {
|
||||
file: buffer,
|
||||
name: `sharpen.${image.type}`
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
const gm = require("gm").subClass({
|
||||
imageMagick: true
|
||||
});
|
||||
const magick = require("../build/Release/image.node");
|
||||
const { promisify } = require("util");
|
||||
|
||||
exports.run = async (message) => {
|
||||
message.channel.sendTyping();
|
||||
const image = await require("../utils/imagedetect.js")(message);
|
||||
if (image === undefined) return `${message.author.mention}, you need to provide an image to add a Shutterstock watermark!`;
|
||||
const watermark = "./assets/images/shutterstock.png";
|
||||
const buffer = await gm(image.path).coalesce().out("null:").out(watermark).gravity("Center").scale(null, "%[fx:u.h]").out("-layers", "composite").bufferPromise(image.type, image.delay);
|
||||
const buffer = await promisify(magick.watermark)(image.path, "./assets/images/shutterstock.png", 5, true, false, false, image.type.toUpperCase(), image.delay ? (100 / image.delay.split("/")[0]) * image.delay.split("/")[1] : 0);
|
||||
return {
|
||||
file: buffer,
|
||||
name: `shutterstock.${image.type}`
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
const gm = require("gm").subClass({
|
||||
imageMagick: true
|
||||
});
|
||||
const magick = require("../build/Release/image.node");
|
||||
const { promisify } = require("util");
|
||||
|
||||
exports.run = async (message) => {
|
||||
message.channel.sendTyping();
|
||||
const image = await require("../utils/imagedetect.js")(message);
|
||||
if (image === undefined) return `${message.author.mention}, you need to provide a GIF to slow down!`;
|
||||
if (image.type !== "gif") return `${message.author.mention}, that isn't a GIF!`;
|
||||
const value = await gm(image.path).identifyPromise();
|
||||
const delay = value.Delay ? value.Delay[0].split("x") : [0, 100];
|
||||
const buffer = await gm().delay(`${parseInt(delay[0]) * 2}x${delay[1]}`).out(image.path).bufferPromise(image.type, image.delay);
|
||||
const buffer = await promisify(magick.speed)(image.path, true, image.type.toUpperCase(), image.delay ? (100 / image.delay.split("/")[0]) * image.delay.split("/")[1] : 0);
|
||||
return {
|
||||
file: buffer,
|
||||
name: "slow.gif"
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
const gm = require("gm").subClass({
|
||||
imageMagick: true
|
||||
});
|
||||
const magick = require("../build/Release/image.node");
|
||||
const { promisify } = require("util");
|
||||
const wrap = require("../utils/wrap.js");
|
||||
|
||||
exports.run = async (message, args) => {
|
||||
if (args.length === 0) return `${message.author.mention}, you need to provide some text to make a Sonic meme!`;
|
||||
message.channel.sendTyping();
|
||||
const template = "./assets/images/sonic.jpg";
|
||||
const file = `/tmp/${Math.random().toString(36).substring(2, 15)}.png`;
|
||||
const cleanedMessage = args.join(" ").replace(/&/g, "\\&").replace(/>/g, "\\>").replace(/</g, "\\<").replace(/"/g, "\\"").replace(/'/g, "\\'");
|
||||
await gm(474, 332).out("+size").background("none").gravity("Center").out("-pointsize", 72).out("-font", "Bitstream Vera Sans").out(`pango:<span foreground="white">${wrap(cleanedMessage, {width: 15, indent: ""})}</span>`).writePromise(file);
|
||||
const buffer = await gm(template).composite(file).gravity("Center").geometry("474x332+160+10").bufferPromise("png", null, "sonic");
|
||||
/*await gm(474, 332).out("+size").background("none").gravity("Center").out("-pointsize", 72).out("-font", "Bitstream Vera Sans").out(`pango:<span foreground="white">${wrap(cleanedMessage, {width: 15, indent: ""})}</span>`).writePromise(file);
|
||||
const buffer = await gm(template).composite(file).gravity("Center").geometry("474x332+160+10").bufferPromise("png", null, "sonic");*/
|
||||
const buffer = await promisify(magick.sonic)(wrap(cleanedMessage, {width: 15, indent: ""}));
|
||||
return {
|
||||
file: buffer,
|
||||
name: "sonic.png"
|
||||
|
|
|
@ -7,8 +7,8 @@ using namespace Magick;
|
|||
|
||||
class BlurWorker : public Napi::AsyncWorker {
|
||||
public:
|
||||
BlurWorker(Napi::Function& callback, string in_path, string type, int delay)
|
||||
: Napi::AsyncWorker(callback), in_path(in_path), type(type), delay(delay) {}
|
||||
BlurWorker(Napi::Function& callback, string in_path, bool sharp, string type, int delay)
|
||||
: Napi::AsyncWorker(callback), in_path(in_path), sharp(sharp), type(type), delay(delay) {}
|
||||
~BlurWorker() {}
|
||||
|
||||
void Execute() {
|
||||
|
@ -20,7 +20,11 @@ class BlurWorker : public Napi::AsyncWorker {
|
|||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||
|
||||
for (Image &image : coalesced) {
|
||||
image.blur(15);
|
||||
if (sharp) {
|
||||
image.sharpen(10, 3);
|
||||
} else {
|
||||
image.blur(15);
|
||||
}
|
||||
image.magick(type);
|
||||
blurred.push_back(image);
|
||||
}
|
||||
|
@ -39,6 +43,7 @@ class BlurWorker : public Napi::AsyncWorker {
|
|||
int delay, wordlength, i, n;
|
||||
size_t bytes, type_size;
|
||||
Blob blob;
|
||||
bool sharp;
|
||||
};
|
||||
|
||||
Napi::Value Blur(const Napi::CallbackInfo &info)
|
||||
|
@ -46,11 +51,12 @@ Napi::Value Blur(const Napi::CallbackInfo &info)
|
|||
Napi::Env env = info.Env();
|
||||
|
||||
string in_path = info[0].As<Napi::String>().Utf8Value();
|
||||
string type = info[1].As<Napi::String>().Utf8Value();
|
||||
int delay = info[2].As<Napi::Number>().Int32Value();
|
||||
Napi::Function cb = info[3].As<Napi::Function>();
|
||||
bool sharp = info[1].As<Napi::Boolean>().Value();
|
||||
string type = info[2].As<Napi::String>().Utf8Value();
|
||||
int delay = info[3].As<Napi::Number>().Int32Value();
|
||||
Napi::Function cb = info[4].As<Napi::Function>();
|
||||
|
||||
BlurWorker* blurWorker = new BlurWorker(cb, in_path, type, delay);
|
||||
BlurWorker* blurWorker = new BlurWorker(cb, in_path, sharp, type, delay);
|
||||
blurWorker->Queue();
|
||||
return env.Undefined();
|
||||
}
|
|
@ -18,6 +18,12 @@
|
|||
#include "magik.h"
|
||||
#include "meme.h"
|
||||
#include "mirror.h"
|
||||
#include "motivate.h"
|
||||
#include "resize.h"
|
||||
#include "reverse.h"
|
||||
#include "scott.h"
|
||||
#include "speed.h"
|
||||
#include "sonic.h"
|
||||
#include "watermark.h"
|
||||
|
||||
Napi::Object Init(Napi::Env env, Napi::Object exports)
|
||||
|
@ -41,6 +47,12 @@ Napi::Object Init(Napi::Env env, Napi::Object exports)
|
|||
exports.Set(Napi::String::New(env, "magik"), Napi::Function::New(env, Magik));
|
||||
exports.Set(Napi::String::New(env, "meme"), Napi::Function::New(env, Meme));
|
||||
exports.Set(Napi::String::New(env, "mirror"), Napi::Function::New(env, Mirror));
|
||||
exports.Set(Napi::String::New(env, "motivate"), Napi::Function::New(env, Motivate));
|
||||
exports.Set(Napi::String::New(env, "resize"), Napi::Function::New(env, Resize));
|
||||
exports.Set(Napi::String::New(env, "reverse"), Napi::Function::New(env, Reverse));
|
||||
exports.Set(Napi::String::New(env, "scott"), Napi::Function::New(env, Scott));
|
||||
exports.Set(Napi::String::New(env, "speed"), Napi::Function::New(env, Speed));
|
||||
exports.Set(Napi::String::New(env, "sonic"), Napi::Function::New(env, Sonic));
|
||||
exports.Set(Napi::String::New(env, "watermark"), Napi::Function::New(env, Watermark));
|
||||
return exports;
|
||||
}
|
||||
|
|
92
natives/motivate.cc
Normal file
92
natives/motivate.cc
Normal file
|
@ -0,0 +1,92 @@
|
|||
#include <napi.h>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
#include <Magick++.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Magick;
|
||||
|
||||
class MotivateWorker : public Napi::AsyncWorker {
|
||||
public:
|
||||
MotivateWorker(Napi::Function& callback, string in_path, string top_text, string bottom_text, string type, int delay)
|
||||
: Napi::AsyncWorker(callback), in_path(in_path), top_text(top_text), bottom_text(bottom_text), type(type), delay(delay) {}
|
||||
~MotivateWorker() {}
|
||||
|
||||
void Execute() {
|
||||
list<Image> frames;
|
||||
list<Image> coalesced;
|
||||
list<Image> mid;
|
||||
list<Image> result;
|
||||
Image top;
|
||||
Image bottom;
|
||||
readImages(&frames, in_path);
|
||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||
|
||||
top.size(Geometry("600"));
|
||||
top.backgroundColor("black");
|
||||
top.font("Times");
|
||||
top.textGravity(Magick::CenterGravity);
|
||||
top.fontPointsize(56);
|
||||
top.read("pango:<span foreground='white'>" + top_text + "</span>");
|
||||
top.extent(Geometry(bottom_text != "" ? to_string(top.columns()) + "x" + to_string(top.rows()) : to_string(top.columns()) + "x" + to_string(top.rows() + 20)), "black", Magick::NorthGravity);
|
||||
|
||||
if (bottom_text != "") {
|
||||
bottom.size(Geometry("600"));
|
||||
bottom.backgroundColor("black");
|
||||
bottom.font("Times");
|
||||
bottom.textGravity(Magick::CenterGravity);
|
||||
bottom.fontPointsize(28);
|
||||
bottom.read("pango:<span foreground='white'>" + bottom_text + "</span>");
|
||||
bottom.extent(Geometry(to_string(bottom.columns()) + "x" + to_string(bottom.rows() + 20)), "black", Magick::NorthGravity);
|
||||
}
|
||||
|
||||
for (Image &image : coalesced) {
|
||||
Image final;
|
||||
image.scale(Geometry(500, 500));
|
||||
image.borderColor("black");
|
||||
image.border(Geometry(5, 5));
|
||||
image.borderColor("white");
|
||||
image.border(Geometry(3, 3));
|
||||
image.backgroundColor("black");
|
||||
image.extent(Geometry(600, image.rows() + 50), Magick::CenterGravity);
|
||||
|
||||
list<Image> to_append;
|
||||
to_append.push_back(image);
|
||||
to_append.push_back(top);
|
||||
if (bottom_text != "") to_append.push_back(bottom);
|
||||
appendImages(&final, to_append.begin(), to_append.end(), true);
|
||||
final.magick(type);
|
||||
mid.push_back(final);
|
||||
}
|
||||
|
||||
optimizeImageLayers(&result, mid.begin(), mid.end());
|
||||
if (delay != 0) for_each(result.begin(), result.end(), animationDelayImage(delay));
|
||||
writeImages(result.begin(), result.end(), &blob);
|
||||
}
|
||||
|
||||
void OnOK() {
|
||||
Callback().Call({Env().Undefined(), Napi::Buffer<char>::Copy(Env(), (char *)blob.data(), blob.length())});
|
||||
}
|
||||
|
||||
private:
|
||||
string in_path, type, top_text, bottom_text;
|
||||
int delay, wordlength, i, n;
|
||||
size_t bytes, type_size;
|
||||
Blob blob;
|
||||
};
|
||||
|
||||
Napi::Value Motivate(const Napi::CallbackInfo &info)
|
||||
{
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
string in_path = info[0].As<Napi::String>().Utf8Value();
|
||||
string top_text = info[1].As<Napi::String>().Utf8Value();
|
||||
string bottom_text = info[2].As<Napi::String>().Utf8Value();
|
||||
string type = info[3].As<Napi::String>().Utf8Value();
|
||||
int delay = info[4].As<Napi::Number>().Int32Value();
|
||||
Napi::Function cb = info[5].As<Napi::Function>();
|
||||
|
||||
MotivateWorker* blurWorker = new MotivateWorker(cb, in_path, top_text, bottom_text, type, delay);
|
||||
blurWorker->Queue();
|
||||
return env.Undefined();
|
||||
}
|
8
natives/motivate.h
Normal file
8
natives/motivate.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef ESMBOT_NATIVES_MOTIVATE_H_
|
||||
#define ESMBOT_NATIVES_MOTIVATE_H_
|
||||
|
||||
#include <napi.h>
|
||||
|
||||
Napi::Value Motivate(const Napi::CallbackInfo& info);
|
||||
|
||||
#endif
|
57
natives/resize.cc
Normal file
57
natives/resize.cc
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include <napi.h>
|
||||
#include <list>
|
||||
#include <Magick++.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Magick;
|
||||
|
||||
class ResizeWorker : public Napi::AsyncWorker {
|
||||
public:
|
||||
ResizeWorker(Napi::Function& callback, string in_path, string type, int delay)
|
||||
: Napi::AsyncWorker(callback), in_path(in_path), type(type), delay(delay) {}
|
||||
~ResizeWorker() {}
|
||||
|
||||
void Execute() {
|
||||
list<Image> frames;
|
||||
list<Image> coalesced;
|
||||
list<Image> blurred;
|
||||
list<Image> result;
|
||||
readImages(&frames, in_path);
|
||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||
|
||||
for (Image &image : coalesced) {
|
||||
image.scale(Geometry("10%"));
|
||||
image.scale(Geometry("1000%"));
|
||||
image.magick(type);
|
||||
blurred.push_back(image);
|
||||
}
|
||||
|
||||
optimizeImageLayers(&result, blurred.begin(), blurred.end());
|
||||
if (delay != 0) for_each(result.begin(), result.end(), animationDelayImage(delay));
|
||||
writeImages(result.begin(), result.end(), &blob);
|
||||
}
|
||||
|
||||
void OnOK() {
|
||||
Callback().Call({Env().Undefined(), Napi::Buffer<char>::Copy(Env(), (char *)blob.data(), blob.length())});
|
||||
}
|
||||
|
||||
private:
|
||||
string in_path, type;
|
||||
int delay, wordlength, i, n, amount;
|
||||
size_t bytes, type_size;
|
||||
Blob blob;
|
||||
};
|
||||
|
||||
Napi::Value Resize(const Napi::CallbackInfo &info)
|
||||
{
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
string in_path = info[0].As<Napi::String>().Utf8Value();
|
||||
string type = info[1].As<Napi::String>().Utf8Value();
|
||||
int delay = info[2].As<Napi::Number>().Int32Value();
|
||||
Napi::Function cb = info[3].As<Napi::Function>();
|
||||
|
||||
ResizeWorker* explodeWorker = new ResizeWorker(cb, in_path, type, delay);
|
||||
explodeWorker->Queue();
|
||||
return env.Undefined();
|
||||
}
|
8
natives/resize.h
Normal file
8
natives/resize.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef ESMBOT_NATIVES_RESIZE_H_
|
||||
#define ESMBOT_NATIVES_RESIZE_H_
|
||||
|
||||
#include <napi.h>
|
||||
|
||||
Napi::Value Resize(const Napi::CallbackInfo& info);
|
||||
|
||||
#endif
|
50
natives/reverse.cc
Normal file
50
natives/reverse.cc
Normal file
|
@ -0,0 +1,50 @@
|
|||
#include <napi.h>
|
||||
#include <list>
|
||||
#include <Magick++.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Magick;
|
||||
|
||||
class ReverseWorker : public Napi::AsyncWorker {
|
||||
public:
|
||||
ReverseWorker(Napi::Function& callback, string in_path, int delay)
|
||||
: Napi::AsyncWorker(callback), in_path(in_path), delay(delay) {}
|
||||
~ReverseWorker() {}
|
||||
|
||||
void Execute() {
|
||||
list<Image> frames;
|
||||
list<Image> coalesced;
|
||||
list<Image> result;
|
||||
readImages(&frames, in_path);
|
||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||
|
||||
coalesced.reverse();
|
||||
|
||||
optimizeImageLayers(&result, coalesced.begin(), coalesced.end());
|
||||
if (delay != 0) for_each(result.begin(), result.end(), animationDelayImage(delay));
|
||||
writeImages(result.begin(), result.end(), &blob);
|
||||
}
|
||||
|
||||
void OnOK() {
|
||||
Callback().Call({Env().Undefined(), Napi::Buffer<char>::Copy(Env(), (char *)blob.data(), blob.length())});
|
||||
}
|
||||
|
||||
private:
|
||||
string in_path, type;
|
||||
int delay, wordlength, i, n, amount;
|
||||
size_t bytes, type_size;
|
||||
Blob blob;
|
||||
};
|
||||
|
||||
Napi::Value Reverse(const Napi::CallbackInfo &info)
|
||||
{
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
string in_path = info[0].As<Napi::String>().Utf8Value();
|
||||
int delay = info[1].As<Napi::Number>().Int32Value();
|
||||
Napi::Function cb = info[2].As<Napi::Function>();
|
||||
|
||||
ReverseWorker* explodeWorker = new ReverseWorker(cb, in_path, delay);
|
||||
explodeWorker->Queue();
|
||||
return env.Undefined();
|
||||
}
|
8
natives/reverse.h
Normal file
8
natives/reverse.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef ESMBOT_NATIVES_REVERSE_H_
|
||||
#define ESMBOT_NATIVES_REVERSE_H_
|
||||
|
||||
#include <napi.h>
|
||||
|
||||
Napi::Value Reverse(const Napi::CallbackInfo& info);
|
||||
|
||||
#endif
|
65
natives/scott.cc
Normal file
65
natives/scott.cc
Normal file
|
@ -0,0 +1,65 @@
|
|||
#include <napi.h>
|
||||
#include <list>
|
||||
#include <Magick++.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Magick;
|
||||
|
||||
class ScottWorker : public Napi::AsyncWorker {
|
||||
public:
|
||||
ScottWorker(Napi::Function& callback, string in_path, string type, int delay)
|
||||
: Napi::AsyncWorker(callback), in_path(in_path), type(type), delay(delay) {}
|
||||
~ScottWorker() {}
|
||||
|
||||
void Execute() {
|
||||
list<Image> frames;
|
||||
list<Image> coalesced;
|
||||
list<Image> mid;
|
||||
list<Image> result;
|
||||
Image watermark;
|
||||
readImages(&frames, in_path);
|
||||
watermark.read("./assets/images/scott.png");
|
||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||
|
||||
for (Image &image : coalesced) {
|
||||
Image watermark_new = watermark;
|
||||
image.virtualPixelMethod(Magick::TransparentVirtualPixelMethod);
|
||||
image.backgroundColor("none");
|
||||
image.scale(Geometry("415x234!"));
|
||||
double arguments[16] = {0, 0, 129, 187, 415, 0, 517, 182, 415, 234, 517, 465, 0, 234, 132, 418};
|
||||
image.distort(Magick::PerspectiveDistortion, 16, arguments, true);
|
||||
image.extent(Geometry("864x481"), Magick::CenterGravity);
|
||||
watermark_new.composite(image, Geometry("-110+83"), Magick::OverCompositeOp);
|
||||
watermark_new.magick(type);
|
||||
mid.push_back(watermark_new);
|
||||
}
|
||||
|
||||
optimizeImageLayers(&result, mid.begin(), mid.end());
|
||||
if (delay != 0) for_each(result.begin(), result.end(), animationDelayImage(delay));
|
||||
writeImages(result.begin(), result.end(), &blob);
|
||||
}
|
||||
|
||||
void OnOK() {
|
||||
Callback().Call({Env().Undefined(), Napi::Buffer<char>::Copy(Env(), (char *)blob.data(), blob.length())});
|
||||
}
|
||||
|
||||
private:
|
||||
string in_path, type;
|
||||
int delay, wordlength, i, n;
|
||||
size_t bytes, type_size;
|
||||
Blob blob;
|
||||
};
|
||||
|
||||
Napi::Value Scott(const Napi::CallbackInfo &info)
|
||||
{
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
string in_path = info[0].As<Napi::String>().Utf8Value();
|
||||
string type = info[1].As<Napi::String>().Utf8Value();
|
||||
int delay = info[2].As<Napi::Number>().Int32Value();
|
||||
Napi::Function cb = info[3].As<Napi::Function>();
|
||||
|
||||
ScottWorker* blurWorker = new ScottWorker(cb, in_path, type, delay);
|
||||
blurWorker->Queue();
|
||||
return env.Undefined();
|
||||
}
|
8
natives/scott.h
Normal file
8
natives/scott.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef ESMBOT_NATIVES_SCOTT_H_
|
||||
#define ESMBOT_NATIVES_SCOTT_H_
|
||||
|
||||
#include <napi.h>
|
||||
|
||||
Napi::Value Scott(const Napi::CallbackInfo& info);
|
||||
|
||||
#endif
|
51
natives/sonic.cc
Normal file
51
natives/sonic.cc
Normal file
|
@ -0,0 +1,51 @@
|
|||
#include <napi.h>
|
||||
#include <list>
|
||||
#include <Magick++.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Magick;
|
||||
|
||||
class SonicWorker : public Napi::AsyncWorker {
|
||||
public:
|
||||
SonicWorker(Napi::Function& callback, string text)
|
||||
: Napi::AsyncWorker(callback), text(text) {}
|
||||
~SonicWorker() {}
|
||||
|
||||
void Execute() {
|
||||
Image image;
|
||||
Image text_image;
|
||||
text_image.backgroundColor("none");
|
||||
text_image.fontPointsize(72);
|
||||
text_image.textGravity(Magick::CenterGravity);
|
||||
text_image.font("Bitstream Vera Sans");
|
||||
text_image.read("pango:<span foreground='white'>" + text + "</span>");
|
||||
text_image.resize(Geometry(474, 332));
|
||||
text_image.extent(Geometry("1024x538-435-145"), Magick::CenterGravity);
|
||||
image.read("./assets/images/sonic.jpg");
|
||||
image.composite(text_image, Geometry("+160+10"), Magick::OverCompositeOp);
|
||||
image.magick("PNG");
|
||||
image.write(&blob);
|
||||
}
|
||||
|
||||
void OnOK() {
|
||||
Callback().Call({Env().Undefined(), Napi::Buffer<char>::Copy(Env(), (char *)blob.data(), blob.length())});
|
||||
}
|
||||
|
||||
private:
|
||||
string text, type;
|
||||
int delay, wordlength, i, n;
|
||||
size_t bytes, type_size;
|
||||
Blob blob;
|
||||
};
|
||||
|
||||
Napi::Value Sonic(const Napi::CallbackInfo &info)
|
||||
{
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
string text = info[0].As<Napi::String>().Utf8Value();
|
||||
Napi::Function cb = info[1].As<Napi::Function>();
|
||||
|
||||
SonicWorker* explodeWorker = new SonicWorker(cb, text);
|
||||
explodeWorker->Queue();
|
||||
return env.Undefined();
|
||||
}
|
8
natives/sonic.h
Normal file
8
natives/sonic.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef ESMBOT_NATIVES_SONIC_H_
|
||||
#define ESMBOT_NATIVES_SONIC_H_
|
||||
|
||||
#include <napi.h>
|
||||
|
||||
Napi::Value Sonic(const Napi::CallbackInfo& info);
|
||||
|
||||
#endif
|
49
natives/speed.cc
Normal file
49
natives/speed.cc
Normal file
|
@ -0,0 +1,49 @@
|
|||
#include <napi.h>
|
||||
#include <list>
|
||||
#include <Magick++.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Magick;
|
||||
|
||||
class SpeedWorker : public Napi::AsyncWorker {
|
||||
public:
|
||||
SpeedWorker(Napi::Function& callback, string in_path, bool slow, string type, int delay)
|
||||
: Napi::AsyncWorker(callback), in_path(in_path), slow(slow), type(type), delay(delay) {}
|
||||
~SpeedWorker() {}
|
||||
|
||||
void Execute() {
|
||||
list<Image> frames;
|
||||
list<Image> blurred;
|
||||
readImages(&frames, in_path);
|
||||
|
||||
for_each(frames.begin(), frames.end(), animationDelayImage(slow ? delay * 2 : delay / 2));
|
||||
|
||||
writeImages(frames.begin(), frames.end(), &blob);
|
||||
}
|
||||
|
||||
void OnOK() {
|
||||
Callback().Call({Env().Undefined(), Napi::Buffer<char>::Copy(Env(), (char *)blob.data(), blob.length())});
|
||||
}
|
||||
|
||||
private:
|
||||
string in_path, type;
|
||||
int delay, wordlength, i, n, amount;
|
||||
size_t bytes, type_size;
|
||||
Blob blob;
|
||||
bool slow;
|
||||
};
|
||||
|
||||
Napi::Value Speed(const Napi::CallbackInfo &info)
|
||||
{
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
string in_path = info[0].As<Napi::String>().Utf8Value();
|
||||
bool slow = info[1].As<Napi::Boolean>().Value();
|
||||
string type = info[2].As<Napi::String>().Utf8Value();
|
||||
int delay = info[3].As<Napi::Number>().Int32Value();
|
||||
Napi::Function cb = info[4].As<Napi::Function>();
|
||||
|
||||
SpeedWorker* explodeWorker = new SpeedWorker(cb, in_path, slow, type, delay);
|
||||
explodeWorker->Queue();
|
||||
return env.Undefined();
|
||||
}
|
8
natives/speed.h
Normal file
8
natives/speed.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef ESMBOT_NATIVES_SPEED_H_
|
||||
#define ESMBOT_NATIVES_SPEED_H_
|
||||
|
||||
#include <napi.h>
|
||||
|
||||
Napi::Value Speed(const Napi::CallbackInfo& info);
|
||||
|
||||
#endif
|
|
@ -32,7 +32,7 @@ const typeCheck = async (image, image2, gifv = false) => {
|
|||
path: path,
|
||||
url: image2
|
||||
};
|
||||
if (gifv) payload.delay = (await execPromise(`ffprobe -v 0 -of csv=p=0 -select_streams v:0 -show_entries stream=r_frame_rate ${path}`)).stdout.replace("\n", "");
|
||||
if (payload.type === "gif") payload.delay = (await execPromise(`ffprobe -v 0 -of csv=p=0 -select_streams v:0 -show_entries stream=r_frame_rate ${path}`)).stdout.replace("\n", "");
|
||||
return payload;
|
||||
} else {
|
||||
// if not, then return false
|
||||
|
|
Loading…
Reference in a new issue