diff --git a/commands/blur.js b/commands/blur.js index 1d6c933..dae0854 100644 --- a/commands/blur.js +++ b/commands/blur.js @@ -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}` diff --git a/commands/motivate.js b/commands/motivate.js index ce7a2cc..047d202 100644 --- a/commands/motivate.js +++ b/commands/motivate.js @@ -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(" Processing... This might take a while"); const [topText, bottomText] = newArgs.join(" ").split(/(? 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, "\\>").replace(/ { 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}` diff --git a/commands/reverse.js b/commands/reverse.js index 8020879..7ef8198 100644 --- a/commands/reverse.js +++ b/commands/reverse.js @@ -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" diff --git a/commands/scott.js b/commands/scott.js index c34d9f5..6be9ff0 100644 --- a/commands/scott.js +++ b/commands/scott.js @@ -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}` diff --git a/commands/sharpen.js b/commands/sharpen.js index c5e339d..f81f749 100644 --- a/commands/sharpen.js +++ b/commands/sharpen.js @@ -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}` diff --git a/commands/shutterstock.js b/commands/shutterstock.js index f373c2d..1454d5c 100644 --- a/commands/shutterstock.js +++ b/commands/shutterstock.js @@ -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}` diff --git a/commands/slow.js b/commands/slow.js index 75dd8e0..686b08e 100644 --- a/commands/slow.js +++ b/commands/slow.js @@ -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" diff --git a/commands/sonic.js b/commands/sonic.js index 261400e..2f1eecb 100644 --- a/commands/sonic.js +++ b/commands/sonic.js @@ -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(/${wrap(cleanedMessage, {width: 15, indent: ""})}`).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:${wrap(cleanedMessage, {width: 15, indent: ""})}`).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" diff --git a/natives/blur.cc b/natives/blur.cc index 212590a..568a737 100644 --- a/natives/blur.cc +++ b/natives/blur.cc @@ -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().Utf8Value(); - string type = info[1].As().Utf8Value(); - int delay = info[2].As().Int32Value(); - Napi::Function cb = info[3].As(); + bool sharp = info[1].As().Value(); + string type = info[2].As().Utf8Value(); + int delay = info[3].As().Int32Value(); + Napi::Function cb = info[4].As(); - BlurWorker* blurWorker = new BlurWorker(cb, in_path, type, delay); + BlurWorker* blurWorker = new BlurWorker(cb, in_path, sharp, type, delay); blurWorker->Queue(); return env.Undefined(); } \ No newline at end of file diff --git a/natives/image.cc b/natives/image.cc index d46c67f..0dba94c 100644 --- a/natives/image.cc +++ b/natives/image.cc @@ -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; } diff --git a/natives/motivate.cc b/natives/motivate.cc new file mode 100644 index 0000000..6b7d1b1 --- /dev/null +++ b/natives/motivate.cc @@ -0,0 +1,92 @@ +#include +#include +#include +#include + +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 frames; + list coalesced; + list mid; + list 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:" + top_text + ""); + 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:" + bottom_text + ""); + 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 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::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().Utf8Value(); + string top_text = info[1].As().Utf8Value(); + string bottom_text = info[2].As().Utf8Value(); + string type = info[3].As().Utf8Value(); + int delay = info[4].As().Int32Value(); + Napi::Function cb = info[5].As(); + + MotivateWorker* blurWorker = new MotivateWorker(cb, in_path, top_text, bottom_text, type, delay); + blurWorker->Queue(); + return env.Undefined(); +} \ No newline at end of file diff --git a/natives/motivate.h b/natives/motivate.h new file mode 100644 index 0000000..a8efa02 --- /dev/null +++ b/natives/motivate.h @@ -0,0 +1,8 @@ +#ifndef ESMBOT_NATIVES_MOTIVATE_H_ +#define ESMBOT_NATIVES_MOTIVATE_H_ + +#include + +Napi::Value Motivate(const Napi::CallbackInfo& info); + +#endif \ No newline at end of file diff --git a/natives/resize.cc b/natives/resize.cc new file mode 100644 index 0000000..dac69a5 --- /dev/null +++ b/natives/resize.cc @@ -0,0 +1,57 @@ +#include +#include +#include + +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 frames; + list coalesced; + list blurred; + list 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::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().Utf8Value(); + string type = info[1].As().Utf8Value(); + int delay = info[2].As().Int32Value(); + Napi::Function cb = info[3].As(); + + ResizeWorker* explodeWorker = new ResizeWorker(cb, in_path, type, delay); + explodeWorker->Queue(); + return env.Undefined(); +} \ No newline at end of file diff --git a/natives/resize.h b/natives/resize.h new file mode 100644 index 0000000..2fb6ffd --- /dev/null +++ b/natives/resize.h @@ -0,0 +1,8 @@ +#ifndef ESMBOT_NATIVES_RESIZE_H_ +#define ESMBOT_NATIVES_RESIZE_H_ + +#include + +Napi::Value Resize(const Napi::CallbackInfo& info); + +#endif \ No newline at end of file diff --git a/natives/reverse.cc b/natives/reverse.cc new file mode 100644 index 0000000..c7d7b8a --- /dev/null +++ b/natives/reverse.cc @@ -0,0 +1,50 @@ +#include +#include +#include + +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 frames; + list coalesced; + list 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::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().Utf8Value(); + int delay = info[1].As().Int32Value(); + Napi::Function cb = info[2].As(); + + ReverseWorker* explodeWorker = new ReverseWorker(cb, in_path, delay); + explodeWorker->Queue(); + return env.Undefined(); +} \ No newline at end of file diff --git a/natives/reverse.h b/natives/reverse.h new file mode 100644 index 0000000..833e682 --- /dev/null +++ b/natives/reverse.h @@ -0,0 +1,8 @@ +#ifndef ESMBOT_NATIVES_REVERSE_H_ +#define ESMBOT_NATIVES_REVERSE_H_ + +#include + +Napi::Value Reverse(const Napi::CallbackInfo& info); + +#endif \ No newline at end of file diff --git a/natives/scott.cc b/natives/scott.cc new file mode 100644 index 0000000..d4ee679 --- /dev/null +++ b/natives/scott.cc @@ -0,0 +1,65 @@ +#include +#include +#include + +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 frames; + list coalesced; + list mid; + list 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::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().Utf8Value(); + string type = info[1].As().Utf8Value(); + int delay = info[2].As().Int32Value(); + Napi::Function cb = info[3].As(); + + ScottWorker* blurWorker = new ScottWorker(cb, in_path, type, delay); + blurWorker->Queue(); + return env.Undefined(); +} \ No newline at end of file diff --git a/natives/scott.h b/natives/scott.h new file mode 100644 index 0000000..76619ed --- /dev/null +++ b/natives/scott.h @@ -0,0 +1,8 @@ +#ifndef ESMBOT_NATIVES_SCOTT_H_ +#define ESMBOT_NATIVES_SCOTT_H_ + +#include + +Napi::Value Scott(const Napi::CallbackInfo& info); + +#endif \ No newline at end of file diff --git a/natives/sonic.cc b/natives/sonic.cc new file mode 100644 index 0000000..83c3b6f --- /dev/null +++ b/natives/sonic.cc @@ -0,0 +1,51 @@ +#include +#include +#include + +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:" + text + ""); + 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::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().Utf8Value(); + Napi::Function cb = info[1].As(); + + SonicWorker* explodeWorker = new SonicWorker(cb, text); + explodeWorker->Queue(); + return env.Undefined(); +} \ No newline at end of file diff --git a/natives/sonic.h b/natives/sonic.h new file mode 100644 index 0000000..e4f751a --- /dev/null +++ b/natives/sonic.h @@ -0,0 +1,8 @@ +#ifndef ESMBOT_NATIVES_SONIC_H_ +#define ESMBOT_NATIVES_SONIC_H_ + +#include + +Napi::Value Sonic(const Napi::CallbackInfo& info); + +#endif \ No newline at end of file diff --git a/natives/speed.cc b/natives/speed.cc new file mode 100644 index 0000000..5bfec50 --- /dev/null +++ b/natives/speed.cc @@ -0,0 +1,49 @@ +#include +#include +#include + +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 frames; + list 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::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().Utf8Value(); + bool slow = info[1].As().Value(); + string type = info[2].As().Utf8Value(); + int delay = info[3].As().Int32Value(); + Napi::Function cb = info[4].As(); + + SpeedWorker* explodeWorker = new SpeedWorker(cb, in_path, slow, type, delay); + explodeWorker->Queue(); + return env.Undefined(); +} \ No newline at end of file diff --git a/natives/speed.h b/natives/speed.h new file mode 100644 index 0000000..06868e2 --- /dev/null +++ b/natives/speed.h @@ -0,0 +1,8 @@ +#ifndef ESMBOT_NATIVES_SPEED_H_ +#define ESMBOT_NATIVES_SPEED_H_ + +#include + +Napi::Value Speed(const Napi::CallbackInfo& info); + +#endif \ No newline at end of file diff --git a/utils/imagedetect.js b/utils/imagedetect.js index 11bfb58..028eb92 100644 --- a/utils/imagedetect.js +++ b/utils/imagedetect.js @@ -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