Added reddit, catch any errors in native functions

This commit is contained in:
TheEssem 2021-04-26 09:47:03 -05:00
parent 6cecd4b9d6
commit b7fe04c82b
41 changed files with 1630 additions and 1386 deletions

View File

@ -46,6 +46,7 @@ WORKDIR /home/esmBot/.internal
COPY ./assets/caption.otf /usr/share/fonts/caption.otf COPY ./assets/caption.otf /usr/share/fonts/caption.otf
COPY ./assets/caption2.ttf /usr/share/fonts/caption2.ttf COPY ./assets/caption2.ttf /usr/share/fonts/caption2.ttf
COPY ./assets/hbc.ttf /usr/share/fonts/hbc.ttf COPY ./assets/hbc.ttf /usr/share/fonts/hbc.ttf
COPY ./assets/reddit.ttf /usr/share/fonts/reddit.ttf
RUN fc-cache -fv RUN fc-cache -fv
COPY --chown=node:node ./package.json package.json COPY --chown=node:node ./package.json package.json

View File

@ -46,6 +46,7 @@ WORKDIR /home/esmBot/.internal
COPY ./assets/caption.otf /usr/share/fonts/caption.otf COPY ./assets/caption.otf /usr/share/fonts/caption.otf
COPY ./assets/caption2.ttf /usr/share/fonts/caption2.ttf COPY ./assets/caption2.ttf /usr/share/fonts/caption2.ttf
COPY ./assets/hbc.ttf /usr/share/fonts/hbc.ttf COPY ./assets/hbc.ttf /usr/share/fonts/hbc.ttf
COPY ./assets/reddit.ttf /usr/share/fonts/reddit.ttf
RUN fc-cache -fv RUN fc-cache -fv
COPY --chown=node:node ./package.json package.json COPY --chown=node:node ./package.json package.json

BIN
assets/images/reddit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
assets/reddit.ttf Normal file

Binary file not shown.

View File

@ -0,0 +1,19 @@
const ImageCommand = require("../../classes/imageCommand.js");
const { random } = require("../../utils/misc.js");
const names = ["esmBot", "me_irl", "dankmemes", "hmmm", "gaming", "wholesome", "chonkers", "memes", "funny", "pcmasterrace", "bellybros"];
class RedditCommand extends ImageCommand {
params(args) {
return {
caption: args.length === 0 ? random(names) : args.join(" ").replaceAll("\n", "").replaceAll(" ", "")
};
}
static description = "Adds a Reddit watermark to an image";
static arguments = ["{text}"];
static noText = "you need to provide some text to add a Reddit watermark!";
static command = "reddit";
}
module.exports = RedditCommand;

View File

@ -9,43 +9,47 @@ using namespace Magick;
Napi::Value Blur(const Napi::CallbackInfo &info) { Napi::Value Blur(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
bool sharp = obj.Get("sharp").As<Napi::Boolean>().Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); bool sharp = obj.Get("sharp").As<Napi::Boolean>().Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
if (sharp) { if (sharp) {
for_each(coalesced.begin(), coalesced.end(), sharpenImage(10, 3)); for_each(coalesced.begin(), coalesced.end(), sharpenImage(10, 3));
} else { } else {
for_each(coalesced.begin(), coalesced.end(), blurImage(15)); for_each(coalesced.begin(), coalesced.end(), blurImage(15));
}
for_each(coalesced.begin(), coalesced.end(), magickImage(type));
optimizeTransparency(coalesced.begin(), coalesced.end());
if (type == "gif") {
for (Image &image : coalesced) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
if (delay != 0) image.animationDelay(delay);
} }
for_each(coalesced.begin(), coalesced.end(), magickImage(type));
optimizeTransparency(coalesced.begin(), coalesced.end());
if (type == "gif") {
for (Image &image : coalesced) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
if (delay != 0) image.animationDelay(delay);
}
}
writeImages(coalesced.begin(), coalesced.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(coalesced.begin(), coalesced.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,42 +9,46 @@ using namespace Magick;
Napi::Value Blurple(const Napi::CallbackInfo &info) { Napi::Value Blurple(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> blurpled; list<Image> blurpled;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
image.threshold(49151.25); image.threshold(49151.25);
image.levelColors("#7289DA", "white"); image.levelColors("#7289DA", "white");
image.magick(type); image.magick(type);
image.animationDelay(delay == 0 ? image.animationDelay() : delay); image.animationDelay(delay == 0 ? image.animationDelay() : delay);
blurpled.push_back(image); blurpled.push_back(image);
}
optimizeTransparency(blurpled.begin(), blurpled.end());
if (type == "gif") {
for (Image &image : blurpled) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
} }
optimizeTransparency(blurpled.begin(), blurpled.end());
if (type == "gif") {
for (Image &image : blurpled) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
}
writeImages(blurpled.begin(), blurpled.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(blurpled.begin(), blurpled.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,62 +9,66 @@ using namespace Magick;
Napi::Value Caption(const Napi::CallbackInfo &info) { Napi::Value Caption(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string caption = obj.Get("caption").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string caption = obj.Get("caption").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> captioned; list<Image> captioned;
readImages(&frames, path); readImages(&frames, path);
size_t width = frames.front().baseColumns(); size_t width = frames.front().baseColumns();
string query(to_string(width - ((width / 25) * 2)) + "x"); string query(to_string(width - ((width / 25) * 2)) + "x");
Image caption_image(Geometry(query), Color("white")); Image caption_image(Geometry(query), Color("white"));
caption_image.fillColor("black"); caption_image.fillColor("black");
caption_image.alpha(true); caption_image.alpha(true);
caption_image.font("Futura"); caption_image.font("Futura");
caption_image.fontPointsize(width / 13); caption_image.fontPointsize(width / 13);
caption_image.textGravity(Magick::CenterGravity); caption_image.textGravity(Magick::CenterGravity);
caption_image.read("pango:" + caption); caption_image.read("pango:" + caption);
caption_image.extent(Geometry(width, caption_image.rows() + (width / 13)), caption_image.extent(Geometry(width, caption_image.rows() + (width / 13)),
Magick::CenterGravity); Magick::CenterGravity);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
Image appended; Image appended;
list<Image> images; list<Image> images;
image.backgroundColor("white"); image.backgroundColor("white");
images.push_back(caption_image); images.push_back(caption_image);
images.push_back(image); images.push_back(image);
appendImages(&appended, images.begin(), images.end(), true); appendImages(&appended, images.begin(), images.end(), true);
appended.repage(); appended.repage();
appended.magick(type); appended.magick(type);
appended.animationDelay(delay == 0 ? image.animationDelay() : delay); appended.animationDelay(delay == 0 ? image.animationDelay() : delay);
appended.gifDisposeMethod(Magick::BackgroundDispose); appended.gifDisposeMethod(Magick::BackgroundDispose);
captioned.push_back(appended); captioned.push_back(appended);
}
optimizeTransparency(captioned.begin(), captioned.end());
if (type == "gif") {
for (Image &image : captioned) {
image.quantizeDither(false);
image.quantize();
} }
optimizeTransparency(captioned.begin(), captioned.end());
if (type == "gif") {
for (Image &image : captioned) {
image.quantizeDither(false);
image.quantize();
}
}
writeImages(captioned.begin(), captioned.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(captioned.begin(), captioned.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,60 +9,64 @@ using namespace Magick;
Napi::Value CaptionTwo(const Napi::CallbackInfo &info) { Napi::Value CaptionTwo(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string caption = obj.Get("caption").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string caption = obj.Get("caption").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> captioned; list<Image> captioned;
Blob caption_blob; Blob caption_blob;
readImages(&frames, path); readImages(&frames, path);
size_t width = frames.front().baseColumns(); size_t width = frames.front().baseColumns();
string query(to_string(width - ((width / 25) * 2)) + "x"); string query(to_string(width - ((width / 25) * 2)) + "x");
Image caption_image(Geometry(query), Color("white")); Image caption_image(Geometry(query), Color("white"));
caption_image.fillColor("black"); caption_image.fillColor("black");
caption_image.font("Helvetica Neue"); caption_image.font("Helvetica Neue");
caption_image.fontPointsize(width / 17); caption_image.fontPointsize(width / 17);
caption_image.read("pango:" + caption); caption_image.read("pango:" + caption);
caption_image.extent(Geometry(width, caption_image.rows() + (width / 25)), caption_image.extent(Geometry(width, caption_image.rows() + (width / 25)),
Magick::CenterGravity); Magick::CenterGravity);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
Image appended; Image appended;
list<Image> images; list<Image> images;
image.backgroundColor("white"); image.backgroundColor("white");
images.push_back(image); images.push_back(image);
images.push_back(caption_image); images.push_back(caption_image);
appendImages(&appended, images.begin(), images.end(), true); appendImages(&appended, images.begin(), images.end(), true);
appended.repage(); appended.repage();
appended.magick(type); appended.magick(type);
appended.animationDelay(delay == 0 ? image.animationDelay() : delay); appended.animationDelay(delay == 0 ? image.animationDelay() : delay);
captioned.push_back(appended); captioned.push_back(appended);
}
optimizeTransparency(captioned.begin(), captioned.end());
if (type == "gif") {
for (Image &image : captioned) {
image.quantizeDither(false);
image.quantize();
} }
optimizeTransparency(captioned.begin(), captioned.end());
if (type == "gif") {
for (Image &image : captioned) {
image.quantizeDither(false);
image.quantize();
}
}
writeImages(captioned.begin(), captioned.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(captioned.begin(), captioned.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,41 +9,45 @@ using namespace Magick;
Napi::Value Circle(const Napi::CallbackInfo &info) { Napi::Value Circle(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> blurred; list<Image> blurred;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
image.rotationalBlur(10); image.rotationalBlur(10);
image.magick(type); image.magick(type);
blurred.push_back(image); blurred.push_back(image);
}
optimizeTransparency(blurred.begin(), blurred.end());
if (type == "gif") {
for (Image &image : blurred) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
if (delay != 0) image.animationDelay(delay);
} }
optimizeTransparency(blurred.begin(), blurred.end());
if (type == "gif") {
for (Image &image : blurred) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
if (delay != 0) image.animationDelay(delay);
}
}
writeImages(blurred.begin(), blurred.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(blurred.begin(), blurred.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,49 +9,53 @@ using namespace Magick;
Napi::Value Crop(const Napi::CallbackInfo &info) { Napi::Value Crop(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
image.extent(Geometry(to_string(image.columns() / image.rows() >= 1 image.extent(Geometry(to_string(image.columns() / image.rows() >= 1
? image.rows() ? image.rows()
: image.columns()) + : image.columns()) +
"x"), "x"),
Magick::CenterGravity); Magick::CenterGravity);
image.extent(Geometry("x" + to_string(image.columns() / image.rows() <= 1 image.extent(Geometry("x" + to_string(image.columns() / image.rows() <= 1
? image.columns() ? image.columns()
: image.rows())), : image.rows())),
Magick::CenterGravity); Magick::CenterGravity);
image.magick(type); image.magick(type);
mid.push_back(image); mid.push_back(image);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
} }
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,42 +9,46 @@ using namespace Magick;
Napi::Value Explode(const Napi::CallbackInfo &info) { Napi::Value Explode(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
int amount = obj.Get("amount").As<Napi::Number>().Int32Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); int amount = obj.Get("amount").As<Napi::Number>().Int32Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> blurred; list<Image> blurred;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
image.implode(amount); image.implode(amount);
image.magick(type); image.magick(type);
blurred.push_back(image); blurred.push_back(image);
}
optimizeTransparency(blurred.begin(), blurred.end());
if (type == "gif") {
for (Image &image : blurred) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
} }
optimizeTransparency(blurred.begin(), blurred.end());
if (type == "gif") {
for (Image &image : blurred) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
}
}
writeImages(blurred.begin(), blurred.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(blurred.begin(), blurred.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,50 +9,54 @@ using namespace Magick;
Napi::Value Flag(const Napi::CallbackInfo &info) { Napi::Value Flag(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string overlay = obj.Get("overlay").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string overlay = obj.Get("overlay").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
Image watermark; Image watermark;
readImages(&frames, path); readImages(&frames, path);
watermark.read(overlay); watermark.read(overlay);
watermark.alphaChannel(Magick::SetAlphaChannel); watermark.alphaChannel(Magick::SetAlphaChannel);
watermark.evaluate(Magick::AlphaChannel, Magick::MultiplyEvaluateOperator, watermark.evaluate(Magick::AlphaChannel, Magick::MultiplyEvaluateOperator,
0.5); 0.5);
string query(to_string(frames.front().baseColumns()) + "x" + string query(to_string(frames.front().baseColumns()) + "x" +
to_string(frames.front().baseRows()) + "!"); to_string(frames.front().baseRows()) + "!");
watermark.scale(Geometry(query)); watermark.scale(Geometry(query));
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
image.composite(watermark, Magick::NorthGravity, Magick::OverCompositeOp); image.composite(watermark, Magick::NorthGravity, Magick::OverCompositeOp);
image.magick(type); image.magick(type);
mid.push_back(image); mid.push_back(image);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
} }
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,43 +9,47 @@ using namespace Magick;
Napi::Value Flip(const Napi::CallbackInfo &info) { Napi::Value Flip(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
bool flop = string path = obj.Get("path").As<Napi::String>().Utf8Value();
obj.Has("flop") ? obj.Get("flop").As<Napi::Boolean>().Value() : false; bool flop =
string type = obj.Get("type").As<Napi::String>().Utf8Value(); obj.Has("flop") ? obj.Get("flop").As<Napi::Boolean>().Value() : false;
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
flop ? image.flop() : image.flip(); flop ? image.flop() : image.flip();
image.magick(type); image.magick(type);
mid.push_back(image); mid.push_back(image);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
} }
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,37 +9,42 @@ using namespace Magick;
Napi::Value Freeze(const Napi::CallbackInfo &info) { Napi::Value Freeze(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
bool loop = string path = obj.Get("path").As<Napi::String>().Utf8Value();
obj.Has("loop") ? obj.Get("loop").As<Napi::Boolean>().Value() : false; bool loop =
string type = obj.Get("type").As<Napi::String>().Utf8Value(); obj.Has("loop") ? obj.Get("loop").As<Napi::Boolean>().Value() : false;
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
int frame = obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
obj.Has("frame") ? obj.Get("frame").As<Napi::Number>().Int32Value() : -1; int frame = obj.Has("frame")
? obj.Get("frame").As<Napi::Number>().Int32Value()
: -1;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
readImages(&frames, path); readImages(&frames, path);
if (frame >= 0 && !loop) { if (frame >= 0 && !loop) {
size_t frameSize = frames.size(); size_t frameSize = frames.size();
int framePos = clamp(frame, 0, (int)frameSize); int framePos = clamp(frame, 0, (int)frameSize);
frames.resize(framePos + 1); frames.resize(framePos + 1);
}
for_each(frames.begin(), frames.end(),
animationIterationsImage(loop ? 0 : 1));
for_each(frames.begin(), frames.end(), magickImage(type));
if (delay != 0)
for_each(frames.begin(), frames.end(), animationDelayImage(delay));
writeImages(frames.begin(), frames.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
for_each(frames.begin(), frames.end(),
animationIterationsImage(loop ? 0 : 1));
for_each(frames.begin(), frames.end(), magickImage(type));
if (delay != 0)
for_each(frames.begin(), frames.end(), animationDelayImage(delay));
writeImages(frames.begin(), frames.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,46 +9,50 @@ using namespace Magick;
Napi::Value Gamexplain(const Napi::CallbackInfo &info) { Napi::Value Gamexplain(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
Image watermark; Image watermark;
readImages(&frames, path); readImages(&frames, path);
watermark.read("./assets/images/gamexplain.png"); watermark.read("./assets/images/gamexplain.png");
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
image.backgroundColor("white"); image.backgroundColor("white");
image.scale(Geometry("1181x571!")); image.scale(Geometry("1181x571!"));
image.extent(Geometry("1200x675-10-92")); image.extent(Geometry("1200x675-10-92"));
image.composite(watermark, Geometry("+0+0"), Magick::OverCompositeOp); image.composite(watermark, Geometry("+0+0"), Magick::OverCompositeOp);
image.magick(type); image.magick(type);
mid.push_back(image); mid.push_back(image);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
} }
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,62 +9,67 @@ using namespace Magick;
Napi::Value Globe(const Napi::CallbackInfo &info) { Napi::Value Globe(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
Image distort; Image distort;
Image overlay; Image overlay;
readImages(&frames, path); readImages(&frames, path);
distort.read("./assets/images/spheremap.png"); distort.read("./assets/images/spheremap.png");
overlay.read("./assets/images/sphere_overlay.png"); overlay.read("./assets/images/sphere_overlay.png");
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
if (type != "gif") { if (type != "gif") {
list<Image>::iterator it = coalesced.begin(); list<Image>::iterator it = coalesced.begin();
for (int i = 0; i < 29; ++i) { for (int i = 0; i < 29; ++i) {
coalesced.push_back(*it); coalesced.push_back(*it);
}
} }
int i = 0;
for (Image &image : coalesced) {
image.scale(Geometry("500x500!"));
image.alphaChannel(Magick::SetAlphaChannel);
size_t width = image.columns();
image.roll(Geometry("+" + to_string(width * i / coalesced.size())));
image.composite(overlay, Magick::CenterGravity,
Magick::HardLightCompositeOp);
image.composite(distort, Magick::CenterGravity,
Magick::DistortCompositeOp);
image.magick("GIF");
mid.push_back(image);
i++;
}
optimizeTransparency(mid.begin(), mid.end());
if (delay != 0) {
for_each(mid.begin(), mid.end(), animationDelayImage(delay));
} else if (type != "gif") {
for_each(mid.begin(), mid.end(), animationDelayImage(5));
}
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
int i = 0;
for (Image &image : coalesced) {
image.scale(Geometry("500x500!"));
image.alphaChannel(Magick::SetAlphaChannel);
size_t width = image.columns();
image.roll(Geometry("+" + to_string(width * i / coalesced.size())));
image.composite(overlay, Magick::CenterGravity,
Magick::HardLightCompositeOp);
image.composite(distort, Magick::CenterGravity, Magick::DistortCompositeOp);
image.magick("GIF");
mid.push_back(image);
i++;
}
optimizeTransparency(mid.begin(), mid.end());
if (delay != 0) {
for_each(mid.begin(), mid.end(), animationDelayImage(delay));
} else if (type != "gif") {
for_each(mid.begin(), mid.end(), animationDelayImage(5));
}
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,25 +9,29 @@ using namespace Magick;
Napi::Value Homebrew(const Napi::CallbackInfo &info) { Napi::Value Homebrew(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string caption = obj.Get("caption").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string caption = obj.Get("caption").As<Napi::String>().Utf8Value();
Blob blob; Blob blob;
Image image; Image image;
image.read("./assets/images/hbc.png"); image.read("./assets/images/hbc.png");
image.textGravity(Magick::CenterGravity); image.textGravity(Magick::CenterGravity);
image.font("./assets/hbc.ttf"); image.font("./assets/hbc.ttf");
image.textKerning(-5); image.textKerning(-5);
image.fillColor("white"); image.fillColor("white");
image.fontPointsize(96); image.fontPointsize(96);
image.draw(DrawableText(0, 0, caption)); image.draw(DrawableText(0, 0, caption));
image.magick("PNG"); image.magick("PNG");
image.write(&blob); image.write(&blob);
Napi::Object result = Napi::Object::New(env); Napi::Object result = Napi::Object::New(env);
result.Set("data", result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length())); blob.length()));
result.Set("type", "png"); result.Set("type", "png");
return result; return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
}
} }

View File

@ -21,6 +21,7 @@
#include "mirror.h" #include "mirror.h"
#include "swirl.h" #include "swirl.h"
#include "motivate.h" #include "motivate.h"
#include "reddit.h"
#include "resize.h" #include "resize.h"
#include "retro.h" #include "retro.h"
#include "reverse.h" #include "reverse.h"
@ -56,6 +57,7 @@ Napi::Object Init(Napi::Env env, Napi::Object exports)
exports.Set(Napi::String::New(env, "meme"), Napi::Function::New(env, Meme)); 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, "mirror"), Napi::Function::New(env, Mirror));
exports.Set(Napi::String::New(env, "motivate"), Napi::Function::New(env, Motivate)); exports.Set(Napi::String::New(env, "motivate"), Napi::Function::New(env, Motivate));
exports.Set(Napi::String::New(env, "reddit"), Napi::Function::New(env, Reddit));
exports.Set(Napi::String::New(env, "resize"), Napi::Function::New(env, Resize)); exports.Set(Napi::String::New(env, "resize"), Napi::Function::New(env, Resize));
exports.Set(Napi::String::New(env, "retro"), Napi::Function::New(env, Retro)); exports.Set(Napi::String::New(env, "retro"), Napi::Function::New(env, Retro));
exports.Set(Napi::String::New(env, "reverse"), Napi::Function::New(env, Reverse)); exports.Set(Napi::String::New(env, "reverse"), Napi::Function::New(env, Reverse));

View File

@ -9,43 +9,47 @@ using namespace Magick;
Napi::Value Invert(const Napi::CallbackInfo &info) { Napi::Value Invert(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for_each(coalesced.begin(), coalesced.end(), negateImage()); for_each(coalesced.begin(), coalesced.end(), negateImage());
for (Image &image : coalesced) { for (Image &image : coalesced) {
image.negateChannel(Magick::AlphaChannel); image.negateChannel(Magick::AlphaChannel);
mid.push_back(image); mid.push_back(image);
}
// Magick::ChannelType(Magick::CompositeChannels ^ Magick::AlphaChannel)
for_each(mid.begin(), mid.end(), magickImage(type));
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
if (delay != 0) image.animationDelay(delay);
} }
// Magick::ChannelType(Magick::CompositeChannels ^ Magick::AlphaChannel)
for_each(mid.begin(), mid.end(), magickImage(type));
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
if (delay != 0) image.animationDelay(delay);
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,20 +9,24 @@ using namespace Magick;
Napi::Value Jpeg(const Napi::CallbackInfo &info) { Napi::Value Jpeg(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string path = obj.Get("path").As<Napi::String>().Utf8Value();
Blob blob; Blob blob;
Image image; Image image;
image.read(path); image.read(path);
image.quality(1); image.quality(1);
image.magick("JPEG"); image.magick("JPEG");
image.write(&blob); image.write(&blob);
Napi::Object result = Napi::Object::New(env); Napi::Object result = Napi::Object::New(env);
result.Set("data", result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length())); blob.length()));
result.Set("type", "jpg"); result.Set("type", "jpg");
return result; return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
}
} }

View File

@ -9,47 +9,51 @@ using namespace Magick;
Napi::Value Leak(const Napi::CallbackInfo &info) { Napi::Value Leak(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
Image watermark; Image watermark;
readImages(&frames, path); readImages(&frames, path);
watermark.read("./assets/images/leak.png"); watermark.read("./assets/images/leak.png");
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
image.backgroundColor("white"); image.backgroundColor("white");
image.scale(Geometry("640x360!")); image.scale(Geometry("640x360!"));
image.rotate(15); image.rotate(15);
image.extent(Geometry("1280x720-700+100")); image.extent(Geometry("1280x720-700+100"));
image.composite(watermark, Geometry("+0+0"), Magick::OverCompositeOp); image.composite(watermark, Geometry("+0+0"), Magick::OverCompositeOp);
image.magick(type); image.magick(type);
mid.push_back(image); mid.push_back(image);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
} }
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,43 +9,47 @@ using namespace Magick;
Napi::Value Magik(const Napi::CallbackInfo &info) { Napi::Value Magik(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> blurred; list<Image> blurred;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
image.scale(Geometry("350x350")); image.scale(Geometry("350x350"));
image.liquidRescale(Geometry("175x175")); image.liquidRescale(Geometry("175x175"));
image.liquidRescale(Geometry("350x350")); image.liquidRescale(Geometry("350x350"));
image.magick(type); image.magick(type);
blurred.push_back(image); blurred.push_back(image);
}
optimizeTransparency(blurred.begin(), blurred.end());
if (type == "gif") {
for (Image &image : blurred) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
if (delay != 0) image.animationDelay(delay);
} }
optimizeTransparency(blurred.begin(), blurred.end());
if (type == "gif") {
for (Image &image : blurred) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
if (delay != 0) image.animationDelay(delay);
}
}
writeImages(blurred.begin(), blurred.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(blurred.begin(), blurred.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,79 +9,84 @@ using namespace Magick;
Napi::Value Meme(const Napi::CallbackInfo &info) { Napi::Value Meme(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string top = obj.Get("top").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
string bottom = obj.Get("bottom").As<Napi::String>().Utf8Value(); string top = obj.Get("top").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string bottom = obj.Get("bottom").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
Image top_text; Image top_text;
Image bottom_text; Image bottom_text;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for_each(coalesced.begin(), coalesced.end(), scaleImage(Geometry(600, 600))); for_each(coalesced.begin(), coalesced.end(),
scaleImage(Geometry(600, 600)));
top_text.size(Geometry(to_string(coalesced.front().columns()))); top_text.size(Geometry(to_string(coalesced.front().columns())));
top_text.backgroundColor("none"); top_text.backgroundColor("none");
top_text.font("Impact"); top_text.font("Impact");
top_text.fontPointsize(40); top_text.fontPointsize(40);
top_text.textGravity(Magick::CenterGravity); top_text.textGravity(Magick::CenterGravity);
top_text.read("pango:<span foreground='white'>" + top + "</span>"); top_text.read("pango:<span foreground='white'>" + top + "</span>");
Image top_text_fill = top_text; Image top_text_fill = top_text;
top_text_fill.channel(Magick::AlphaChannel); top_text_fill.channel(Magick::AlphaChannel);
top_text_fill.morphology(Magick::EdgeOutMorphology, "Octagon"); top_text_fill.morphology(Magick::EdgeOutMorphology, "Octagon");
top_text_fill.backgroundColor("black"); top_text_fill.backgroundColor("black");
top_text_fill.alphaChannel(Magick::ShapeAlphaChannel); top_text_fill.alphaChannel(Magick::ShapeAlphaChannel);
top_text.composite(top_text_fill, Magick::CenterGravity, top_text.composite(top_text_fill, Magick::CenterGravity,
Magick::DstOverCompositeOp); Magick::DstOverCompositeOp);
if (bottom != "") { if (bottom != "") {
bottom_text.size(Geometry(to_string(coalesced.front().columns()))); bottom_text.size(Geometry(to_string(coalesced.front().columns())));
bottom_text.backgroundColor("none"); bottom_text.backgroundColor("none");
bottom_text.font("Impact"); bottom_text.font("Impact");
bottom_text.fontPointsize(40); bottom_text.fontPointsize(40);
bottom_text.textGravity(Magick::CenterGravity); bottom_text.textGravity(Magick::CenterGravity);
bottom_text.read("pango:<span foreground='white'>" + bottom + "</span>"); bottom_text.read("pango:<span foreground='white'>" + bottom + "</span>");
Image bottom_text_fill = bottom_text; Image bottom_text_fill = bottom_text;
bottom_text_fill.channel(Magick::AlphaChannel); bottom_text_fill.channel(Magick::AlphaChannel);
bottom_text_fill.morphology(Magick::EdgeOutMorphology, "Octagon"); bottom_text_fill.morphology(Magick::EdgeOutMorphology, "Octagon");
bottom_text_fill.backgroundColor("black"); bottom_text_fill.backgroundColor("black");
bottom_text_fill.alphaChannel(Magick::ShapeAlphaChannel); bottom_text_fill.alphaChannel(Magick::ShapeAlphaChannel);
bottom_text.composite(bottom_text_fill, Magick::CenterGravity, bottom_text.composite(bottom_text_fill, Magick::CenterGravity,
Magick::DstOverCompositeOp); Magick::DstOverCompositeOp);
}
for (Image &image : coalesced) {
image.composite(top_text, Magick::NorthGravity, Magick::OverCompositeOp);
if (bottom != "")
image.composite(bottom_text, Magick::SouthGravity,
Magick::OverCompositeOp);
image.magick(type);
mid.push_back(image);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
} }
for (Image &image : coalesced) {
image.composite(top_text, Magick::NorthGravity, Magick::OverCompositeOp);
if (bottom != "")
image.composite(bottom_text, Magick::SouthGravity,
Magick::OverCompositeOp);
image.magick(type);
mid.push_back(image);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,78 +9,82 @@ using namespace Magick;
Napi::Value Mirror(const Napi::CallbackInfo &info) { Napi::Value Mirror(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
bool vertical = obj.Has("vertical") string path = obj.Get("path").As<Napi::String>().Utf8Value();
? obj.Get("vertical").As<Napi::Boolean>().Value() bool vertical = obj.Has("vertical")
: false; ? obj.Get("vertical").As<Napi::Boolean>().Value()
bool first = : false;
obj.Has("first") ? obj.Get("first").As<Napi::Boolean>().Value() : false; bool first =
string type = obj.Get("type").As<Napi::String>().Utf8Value(); obj.Has("first") ? obj.Get("first").As<Napi::Boolean>().Value() : false;
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
MagickCore::GravityType gravity; MagickCore::GravityType gravity;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
if (vertical && first) { if (vertical && first) {
gravity = Magick::NorthGravity; gravity = Magick::NorthGravity;
} else if (!vertical && first) { } else if (!vertical && first) {
gravity = Magick::WestGravity; gravity = Magick::WestGravity;
} else if (vertical && !first) { } else if (vertical && !first) {
gravity = Magick::SouthGravity; gravity = Magick::SouthGravity;
} else {
gravity = Magick::EastGravity;
}
for (Image &image : coalesced) {
list<Image> mirrored;
Image final;
image.extent(
Geometry(to_string(vertical ? image.baseColumns()
: image.baseColumns() / 2) +
"x" +
to_string(vertical ? image.baseRows() / 2 : image.baseRows())),
gravity);
mirrored.push_back(image);
Image mirror = image;
if (vertical) {
mirror.flip();
} else { } else {
mirror.flop(); gravity = Magick::EastGravity;
} }
if (first) {
mirrored.push_back(mirror); for (Image &image : coalesced) {
} else { list<Image> mirrored;
mirrored.push_front(mirror); Image final;
image.extent(Geometry(to_string(vertical ? image.baseColumns()
: image.baseColumns() / 2) +
"x" +
to_string(vertical ? image.baseRows() / 2
: image.baseRows())),
gravity);
mirrored.push_back(image);
Image mirror = image;
if (vertical) {
mirror.flip();
} else {
mirror.flop();
}
if (first) {
mirrored.push_back(mirror);
} else {
mirrored.push_front(mirror);
}
appendImages(&final, mirrored.begin(), mirrored.end(), vertical);
final.repage();
final.magick(type);
final.animationDelay(delay == 0 ? image.animationDelay() : delay);
mid.push_back(final);
} }
appendImages(&final, mirrored.begin(), mirrored.end(), vertical);
final.repage(); optimizeTransparency(mid.begin(), mid.end());
final.magick(type);
final.animationDelay(delay == 0 ? image.animationDelay() : delay); if (type == "gif") {
mid.push_back(final); for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,83 +9,87 @@ using namespace Magick;
Napi::Value Motivate(const Napi::CallbackInfo &info) { Napi::Value Motivate(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string top_text = obj.Get("top").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
string bottom_text = obj.Get("bottom").As<Napi::String>().Utf8Value(); string top_text = obj.Get("top").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string bottom_text = obj.Get("bottom").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
Image top; Image top;
Image bottom; Image bottom;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
top.size(Geometry("600")); top.size(Geometry("600"));
top.backgroundColor("black"); top.backgroundColor("black");
top.font("Times"); top.font("Times");
top.textGravity(Magick::CenterGravity); top.textGravity(Magick::CenterGravity);
top.fontPointsize(56); top.fontPointsize(56);
top.read("pango:<span foreground='white'>" + top_text + "</span>"); top.read("pango:<span foreground='white'>" + top_text + "</span>");
top.extent(Geometry(bottom_text != "" ? to_string(top.columns()) + "x" + top.extent(Geometry(bottom_text != "" ? to_string(top.columns()) + "x" +
to_string(top.rows()) to_string(top.rows())
: to_string(top.columns()) + "x" + : to_string(top.columns()) + "x" +
to_string(top.rows() + 20)), to_string(top.rows() + 20)),
"black", Magick::NorthGravity); "black", Magick::NorthGravity);
if (bottom_text != "") { if (bottom_text != "") {
bottom.size(Geometry("600")); bottom.size(Geometry("600"));
bottom.backgroundColor("black"); bottom.backgroundColor("black");
bottom.font("Times"); bottom.font("Times");
bottom.textGravity(Magick::CenterGravity); bottom.textGravity(Magick::CenterGravity);
bottom.fontPointsize(28); bottom.fontPointsize(28);
bottom.read("pango:<span foreground='white'>" + bottom_text + "</span>"); bottom.read("pango:<span foreground='white'>" + bottom_text + "</span>");
bottom.extent(Geometry(to_string(bottom.columns()) + "x" + bottom.extent(Geometry(to_string(bottom.columns()) + "x" +
to_string(bottom.rows() + 20)), to_string(bottom.rows() + 20)),
"black", Magick::NorthGravity); "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.repage();
final.magick(type);
final.animationDelay(delay == 0 ? image.animationDelay() : delay);
mid.push_back(final);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
} }
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.repage();
final.magick(type);
final.animationDelay(delay == 0 ? image.animationDelay() : delay);
mid.push_back(final);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

74
natives/reddit.cc Normal file
View File

@ -0,0 +1,74 @@
#include <Magick++.h>
#include <napi.h>
#include <list>
using namespace std;
using namespace Magick;
Napi::Value Reddit(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
try {
Napi::Object obj = info[0].As<Napi::Object>();
string path = obj.Get("path").As<Napi::String>().Utf8Value();
string text = obj.Get("caption").As<Napi::String>().Utf8Value();
string type = obj.Get("type").As<Napi::String>().Utf8Value();
int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob;
list<Image> frames;
list<Image> coalesced;
list<Image> mid;
Image watermark;
Image text_image;
readImages(&frames, path);
watermark.read("./assets/images/reddit.png");
text_image.textGravity(Magick::WestGravity);
text_image.font("Roboto");
text_image.fontPointsize(47);
text_image.backgroundColor("none");
text_image.read("pango:<span foreground='white'>" + text + "</span>");
watermark.composite(text_image, Geometry("+375+46"),
Magick::OverCompositeOp);
string query(to_string(frames.front().baseColumns()) + "x");
watermark.scale(Geometry(query));
coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) {
Image final;
list<Image> to_append;
to_append.push_back(image);
to_append.push_back(watermark);
appendImages(&final, to_append.begin(), to_append.end(), true);
final.repage();
image.magick(type);
final.animationDelay(delay == 0 ? image.animationDelay() : delay);
mid.push_back(final);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
}
}

8
natives/reddit.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef ESMBOT_NATIVES_REDDIT_H_
#define ESMBOT_NATIVES_REDDIT_H_
#include <napi.h>
Napi::Value Reddit(const Napi::CallbackInfo& info);
#endif

View File

@ -9,54 +9,58 @@ using namespace Magick;
Napi::Value Resize(const Napi::CallbackInfo &info) { Napi::Value Resize(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
bool stretch = obj.Has("stretch") string path = obj.Get("path").As<Napi::String>().Utf8Value();
? obj.Get("stretch").As<Napi::Boolean>().Value() bool stretch = obj.Has("stretch")
: false; ? obj.Get("stretch").As<Napi::Boolean>().Value()
bool wide = : false;
obj.Has("wide") ? obj.Get("wide").As<Napi::Boolean>().Value() : false; bool wide =
string type = obj.Get("type").As<Napi::String>().Utf8Value(); obj.Has("wide") ? obj.Get("wide").As<Napi::Boolean>().Value() : false;
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> blurred; list<Image> blurred;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
if (stretch) { if (stretch) {
image.resize(Geometry("512x512!")); image.resize(Geometry("512x512!"));
} else if (wide) { } else if (wide) {
image.resize(Geometry(to_string((image.baseColumns() * 19) / 2) + "x" + image.resize(Geometry(to_string((image.baseColumns() * 19) / 2) + "x" +
to_string(image.baseRows() / 2) + "!")); to_string(image.baseRows() / 2) + "!"));
} else { } else {
image.scale(Geometry("10%")); image.scale(Geometry("10%"));
image.scale(Geometry("1000%")); image.scale(Geometry("1000%"));
}
image.magick(type);
blurred.push_back(image);
} }
image.magick(type);
blurred.push_back(image);
}
optimizeTransparency(blurred.begin(), blurred.end()); optimizeTransparency(blurred.begin(), blurred.end());
if (type == "gif") { if (type == "gif") {
for (Image &image : blurred) { for (Image &image : blurred) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod); image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize(); image.quantize();
if (delay != 0) image.animationDelay(delay); if (delay != 0) image.animationDelay(delay);
}
} }
writeImages(blurred.begin(), blurred.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(blurred.begin(), blurred.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,76 +9,80 @@ using namespace Magick;
Napi::Value Retro(const Napi::CallbackInfo &info) { Napi::Value Retro(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string line1 = obj.Get("line1").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string line2 = obj.Get("line2").As<Napi::String>().Utf8Value(); string line1 = obj.Get("line1").As<Napi::String>().Utf8Value();
string line3 = obj.Get("line3").As<Napi::String>().Utf8Value(); string line2 = obj.Get("line2").As<Napi::String>().Utf8Value();
string line3 = obj.Get("line3").As<Napi::String>().Utf8Value();
Blob blob; Blob blob;
Image image; Image image;
Image line1_text; Image line1_text;
Image line2_text; Image line2_text;
Image line3_text; Image line3_text;
image.read("./assets/images/retro.png"); image.read("./assets/images/retro.png");
line2_text.backgroundColor("none"); line2_text.backgroundColor("none");
line2_text.fontPointsize(128); line2_text.fontPointsize(128);
line2_text.textGravity(Magick::CenterGravity); line2_text.textGravity(Magick::CenterGravity);
line2_text.font("Comic Sans MS"); line2_text.font("Comic Sans MS");
line2_text.read("pango:<span foreground='white'>" + line2_text.read("pango:<span foreground='white'>" +
(line2 == "" ? line1 : line2) + "</span>"); (line2 == "" ? line1 : line2) + "</span>");
line2_text.extent(Geometry("1260x859+0+0"), Magick::CenterGravity); line2_text.extent(Geometry("1260x859+0+0"), Magick::CenterGravity);
Image line2_text_fill = line2_text; Image line2_text_fill = line2_text;
line2_text_fill.channel(Magick::AlphaChannel); line2_text_fill.channel(Magick::AlphaChannel);
line2_text_fill.morphology(Magick::EdgeOutMorphology, "Octagon:10"); line2_text_fill.morphology(Magick::EdgeOutMorphology, "Octagon:10");
line2_text_fill.backgroundColor("gray"); line2_text_fill.backgroundColor("gray");
line2_text_fill.alphaChannel(Magick::ShapeAlphaChannel); line2_text_fill.alphaChannel(Magick::ShapeAlphaChannel);
line2_text.composite(line2_text_fill, Magick::CenterGravity, line2_text.composite(line2_text_fill, Magick::CenterGravity,
Magick::DstOverCompositeOp);
image.composite(line2_text, Geometry("+0-100"), Magick::OverCompositeOp);
if (line2 != "") {
line1_text.backgroundColor("none");
line1_text.fontPointsize(64);
line1_text.textGravity(Magick::CenterGravity);
line1_text.font("Comic Sans MS");
line1_text.read("pango:<span foreground='white'>" + line1 + "</span>");
line1_text.extent(Geometry("1260x859+0+0"), Magick::CenterGravity);
Image line1_text_fill = line1_text;
line1_text_fill.channel(Magick::AlphaChannel);
line1_text_fill.morphology(Magick::EdgeOutMorphology, "Octagon:10");
line1_text_fill.backgroundColor("gray");
line1_text_fill.alphaChannel(Magick::ShapeAlphaChannel);
line1_text.composite(line1_text_fill, Magick::CenterGravity,
Magick::DstOverCompositeOp); Magick::DstOverCompositeOp);
image.composite(line1_text, Geometry("+0-250"), Magick::OverCompositeOp); image.composite(line2_text, Geometry("+0-100"), Magick::OverCompositeOp);
if (line2 != "") {
line1_text.backgroundColor("none");
line1_text.fontPointsize(64);
line1_text.textGravity(Magick::CenterGravity);
line1_text.font("Comic Sans MS");
line1_text.read("pango:<span foreground='white'>" + line1 + "</span>");
line1_text.extent(Geometry("1260x859+0+0"), Magick::CenterGravity);
Image line1_text_fill = line1_text;
line1_text_fill.channel(Magick::AlphaChannel);
line1_text_fill.morphology(Magick::EdgeOutMorphology, "Octagon:10");
line1_text_fill.backgroundColor("gray");
line1_text_fill.alphaChannel(Magick::ShapeAlphaChannel);
line1_text.composite(line1_text_fill, Magick::CenterGravity,
Magick::DstOverCompositeOp);
image.composite(line1_text, Geometry("+0-250"), Magick::OverCompositeOp);
}
if (line3 != "") {
line3_text.backgroundColor("none");
line3_text.fontPointsize(64);
line3_text.textGravity(Magick::CenterGravity);
line3_text.font("Comic Sans MS");
line3_text.read("pango:<span foreground='white'>" + line3 + "</span>");
line3_text.extent(Geometry("1260x859+0+0"), Magick::CenterGravity);
Image line3_text_fill = line3_text;
line3_text_fill.channel(Magick::AlphaChannel);
line3_text_fill.morphology(Magick::EdgeOutMorphology, "Octagon:10");
line3_text_fill.backgroundColor("gray");
line3_text_fill.alphaChannel(Magick::ShapeAlphaChannel);
line3_text.composite(line3_text_fill, Magick::CenterGravity,
Magick::DstOverCompositeOp);
image.composite(line3_text, Geometry("+0+50"), Magick::OverCompositeOp);
}
image.magick("PNG");
image.write(&blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", "png");
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
if (line3 != "") {
line3_text.backgroundColor("none");
line3_text.fontPointsize(64);
line3_text.textGravity(Magick::CenterGravity);
line3_text.font("Comic Sans MS");
line3_text.read("pango:<span foreground='white'>" + line3 + "</span>");
line3_text.extent(Geometry("1260x859+0+0"), Magick::CenterGravity);
Image line3_text_fill = line3_text;
line3_text_fill.channel(Magick::AlphaChannel);
line3_text_fill.morphology(Magick::EdgeOutMorphology, "Octagon:10");
line3_text_fill.backgroundColor("gray");
line3_text_fill.alphaChannel(Magick::ShapeAlphaChannel);
line3_text.composite(line3_text_fill, Magick::CenterGravity,
Magick::DstOverCompositeOp);
image.composite(line3_text, Geometry("+0+50"), Magick::OverCompositeOp);
}
image.magick("PNG");
image.write(&blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", "png");
return result;
} }

View File

@ -9,43 +9,47 @@ using namespace Magick;
Napi::Value Reverse(const Napi::CallbackInfo &info) { Napi::Value Reverse(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
bool soos = string path = obj.Get("path").As<Napi::String>().Utf8Value();
obj.Has("soos") ? obj.Get("soos").As<Napi::Boolean>().Value() : false; bool soos =
int delay = obj.Has("soos") ? obj.Get("soos").As<Napi::Boolean>().Value() : false;
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
if (soos) { if (soos) {
list<Image> copy = coalesced; list<Image> copy = coalesced;
copy.reverse(); copy.reverse();
coalesced.insert(coalesced.end(), copy.begin(), copy.end()); coalesced.insert(coalesced.end(), copy.begin(), copy.end());
} else { } else {
coalesced.reverse(); coalesced.reverse();
}
for_each(coalesced.begin(), coalesced.end(), magickImage("GIF"));
optimizeTransparency(coalesced.begin(), coalesced.end());
for (Image &image : coalesced) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
}
writeImages(coalesced.begin(), coalesced.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", "gif");
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
for_each(coalesced.begin(), coalesced.end(), magickImage("GIF"));
optimizeTransparency(coalesced.begin(), coalesced.end());
for (Image &image : coalesced) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
}
writeImages(coalesced.begin(), coalesced.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", "gif");
return result;
} }

View File

@ -9,52 +9,56 @@ using namespace Magick;
Napi::Value Scott(const Napi::CallbackInfo &info) { Napi::Value Scott(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
Image watermark; Image watermark;
readImages(&frames, path); readImages(&frames, path);
watermark.read("./assets/images/scott.png"); watermark.read("./assets/images/scott.png");
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
Image watermark_new = watermark; Image watermark_new = watermark;
image.virtualPixelMethod(Magick::TransparentVirtualPixelMethod); image.virtualPixelMethod(Magick::TransparentVirtualPixelMethod);
image.backgroundColor("none"); image.backgroundColor("none");
image.scale(Geometry("415x234!")); image.scale(Geometry("415x234!"));
double arguments[16] = {0, 0, 129, 187, 415, 0, 517, 182, double arguments[16] = {0, 0, 129, 187, 415, 0, 517, 182,
415, 234, 517, 465, 0, 234, 132, 418}; 415, 234, 517, 465, 0, 234, 132, 418};
image.distort(Magick::PerspectiveDistortion, 16, arguments, true); image.distort(Magick::PerspectiveDistortion, 16, arguments, true);
image.extent(Geometry("864x481"), Magick::CenterGravity); image.extent(Geometry("864x481"), Magick::CenterGravity);
watermark_new.composite(image, Geometry("-110+83"), watermark_new.composite(image, Geometry("-110+83"),
Magick::OverCompositeOp); Magick::OverCompositeOp);
watermark_new.magick(type); watermark_new.magick(type);
watermark_new.animationDelay(delay == 0 ? image.animationDelay() : delay); watermark_new.animationDelay(delay == 0 ? image.animationDelay() : delay);
mid.push_back(watermark_new); mid.push_back(watermark_new);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
} }
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,28 +9,32 @@ using namespace Magick;
Napi::Value Sonic(const Napi::CallbackInfo &info) { Napi::Value Sonic(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string text = obj.Get("text").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string text = obj.Get("text").As<Napi::String>().Utf8Value();
Blob blob; Blob blob;
Image image; Image image;
Image text_image; Image text_image;
text_image.backgroundColor("none"); text_image.backgroundColor("none");
text_image.fontPointsize(72); text_image.fontPointsize(72);
text_image.textGravity(Magick::CenterGravity); text_image.textGravity(Magick::CenterGravity);
text_image.font("Bitstream Vera Sans"); text_image.font("Bitstream Vera Sans");
text_image.read("pango:<span foreground='white'>" + text + "</span>"); text_image.read("pango:<span foreground='white'>" + text + "</span>");
text_image.resize(Geometry(474, 332)); text_image.resize(Geometry(474, 332));
text_image.extent(Geometry("1024x538-435-145"), Magick::CenterGravity); text_image.extent(Geometry("1024x538-435-145"), Magick::CenterGravity);
image.read("./assets/images/sonic.jpg"); image.read("./assets/images/sonic.jpg");
image.composite(text_image, Geometry("+160+10"), Magick::OverCompositeOp); image.composite(text_image, Geometry("+160+10"), Magick::OverCompositeOp);
image.magick("PNG"); image.magick("PNG");
image.write(&blob); image.write(&blob);
Napi::Object result = Napi::Object::New(env); Napi::Object result = Napi::Object::New(env);
result.Set("data", result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length())); blob.length()));
result.Set("type", "png"); result.Set("type", "png");
return result; return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
}
} }

View File

@ -9,70 +9,76 @@ using namespace Magick;
Napi::Value Speed(const Napi::CallbackInfo &info) { Napi::Value Speed(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
bool slow = string path = obj.Get("path").As<Napi::String>().Utf8Value();
obj.Has("slow") ? obj.Get("slow").As<Napi::Boolean>().Value() : false; bool slow =
string type = obj.Get("type").As<Napi::String>().Utf8Value(); obj.Has("slow") ? obj.Get("slow").As<Napi::Boolean>().Value() : false;
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
int speed = obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
obj.Has("speed") ? obj.Get("speed").As<Napi::Number>().Int32Value() : 2; int speed =
obj.Has("speed") ? obj.Get("speed").As<Napi::Number>().Int32Value() : 2;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
readImages(&frames, path); readImages(&frames, path);
// if passed a delay, use that. otherwise use the average frame delay. // if passed a delay, use that. otherwise use the average frame delay.
if (delay == 0) { if (delay == 0) {
vector<int> old_delays; vector<int> old_delays;
bool removeFrames = false; bool removeFrames = false;
for (Image &image : frames) { for (Image &image : frames) {
int animation_delay = image.animationDelay(); int animation_delay = image.animationDelay();
old_delays.push_back(animation_delay); old_delays.push_back(animation_delay);
}
for (Image &image : frames) {
int old_delay = image.animationDelay();
int new_delay = slow ? old_delay * speed : old_delay / speed;
if (!slow && new_delay <= 1) {
removeFrames = true;
break;
}
image.animationDelay(new_delay);
}
if (removeFrames) {
for (list<Image>::iterator i = frames.begin(); i != frames.end(); ++i) {
int index = distance(frames.begin(), i);
i->animationDelay(old_delays[index]);
} }
for (int i = 0; i < speed - 1; ++i) { for (Image &image : frames) {
frames.remove_if( int old_delay = image.animationDelay();
[counter = 0](const auto x) mutable { return ++counter % 2 == 0; }); int new_delay = slow ? old_delay * speed : old_delay / speed;
if (!slow && new_delay <= 1) {
removeFrames = true;
break;
}
image.animationDelay(new_delay);
} }
}
} else { if (removeFrames) {
int new_delay = slow ? delay * speed : delay / speed; for (list<Image>::iterator i = frames.begin(); i != frames.end(); ++i) {
if (!slow && new_delay <= 1) { int index = distance(frames.begin(), i);
for (int i = 0; i < speed - 1; ++i) { i->animationDelay(old_delays[index]);
frames.remove_if( }
[counter = 0](const auto x) mutable { return ++counter % 2 == 0; });
for (int i = 0; i < speed - 1; ++i) {
frames.remove_if([counter = 0](const auto x) mutable {
return ++counter % 2 == 0;
});
}
} }
} else { } else {
for_each(frames.begin(), frames.end(), animationDelayImage(new_delay)); int new_delay = slow ? delay * speed : delay / speed;
if (!slow && new_delay <= 1) {
for (int i = 0; i < speed - 1; ++i) {
frames.remove_if([counter = 0](const auto x) mutable {
return ++counter % 2 == 0;
});
}
} else {
for_each(frames.begin(), frames.end(), animationDelayImage(new_delay));
}
} }
for_each(frames.begin(), frames.end(), magickImage(type));
writeImages(frames.begin(), frames.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
for_each(frames.begin(), frames.end(), magickImage(type));
writeImages(frames.begin(), frames.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,59 +9,63 @@ using namespace Magick;
Napi::Value Spin(const Napi::CallbackInfo &info) { Napi::Value Spin(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
if (type != "gif") { if (type != "gif") {
list<Image>::iterator it = coalesced.begin(); list<Image>::iterator it = coalesced.begin();
for (int i = 0; i < 29; ++i) { for (int i = 0; i < 29; ++i) {
coalesced.push_back(*it); coalesced.push_back(*it);
}
} }
int i = 0;
for (Image &image : coalesced) {
image.virtualPixelMethod(Magick::TransparentVirtualPixelMethod);
image.scale(Geometry("256x256"));
image.alphaChannel(Magick::SetAlphaChannel);
double rotation[1] = {360 * i / coalesced.size()};
image.distort(Magick::ScaleRotateTranslateDistortion, 1, rotation);
image.magick("GIF");
mid.push_back(image);
i++;
}
for_each(mid.begin(), mid.end(),
gifDisposeMethodImage(Magick::BackgroundDispose));
optimizeTransparency(mid.begin(), mid.end());
if (delay != 0) {
for_each(mid.begin(), mid.end(), animationDelayImage(delay));
} else if (type != "gif") {
for_each(mid.begin(), mid.end(), animationDelayImage(5));
}
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", "gif");
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
int i = 0;
for (Image &image : coalesced) {
image.virtualPixelMethod(Magick::TransparentVirtualPixelMethod);
image.scale(Geometry("256x256"));
image.alphaChannel(Magick::SetAlphaChannel);
double rotation[1] = {360 * i / coalesced.size()};
image.distort(Magick::ScaleRotateTranslateDistortion, 1, rotation);
image.magick("GIF");
mid.push_back(image);
i++;
}
for_each(mid.begin(), mid.end(),
gifDisposeMethodImage(Magick::BackgroundDispose));
optimizeTransparency(mid.begin(), mid.end());
if (delay != 0) {
for_each(mid.begin(), mid.end(), animationDelayImage(delay));
} else if (type != "gif") {
for_each(mid.begin(), mid.end(), animationDelayImage(5));
}
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", "gif");
return result;
} }

View File

@ -9,41 +9,45 @@ using namespace Magick;
Napi::Value Swirl(const Napi::CallbackInfo &info) { Napi::Value Swirl(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
image.swirl(180); image.swirl(180);
image.magick(type); image.magick(type);
mid.push_back(image); mid.push_back(image);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
} }
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDither(false);
image.quantize();
if (delay != 0) image.animationDelay(delay);
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,55 +9,59 @@ using namespace Magick;
Napi::Value Tile(const Napi::CallbackInfo &info) { Napi::Value Tile(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
list<Image> duplicated; list<Image> duplicated;
Image appended; Image appended;
list<Image> montage; list<Image> montage;
Image frame; Image frame;
image.magick(type); image.magick(type);
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
duplicated.push_back(image); duplicated.push_back(image);
}
appendImages(&appended, duplicated.begin(), duplicated.end());
appended.repage();
for (int i = 0; i < 5; ++i) {
montage.push_back(appended);
}
appendImages(&frame, montage.begin(), montage.end(), true);
frame.repage();
frame.scale(Geometry("800x800>"));
frame.animationDelay(delay == 0 ? image.animationDelay() : delay);
mid.push_back(frame);
} }
appendImages(&appended, duplicated.begin(), duplicated.end());
appended.repage(); optimizeTransparency(mid.begin(), mid.end());
for (int i = 0; i < 5; ++i) {
montage.push_back(appended); if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
} }
appendImages(&frame, montage.begin(), montage.end(), true);
frame.repage(); writeImages(mid.begin(), mid.end(), &blob);
frame.scale(Geometry("800x800>"));
frame.animationDelay(delay == 0 ? image.animationDelay() : delay); Napi::Object result = Napi::Object::New(env);
mid.push_back(frame); result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,52 +9,56 @@ using namespace Magick;
Napi::Value Trump(const Napi::CallbackInfo &info) { Napi::Value Trump(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
Image watermark; Image watermark;
readImages(&frames, path); readImages(&frames, path);
watermark.read("./assets/images/trump.png"); watermark.read("./assets/images/trump.png");
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
Image watermark_new = watermark; Image watermark_new = watermark;
image.virtualPixelMethod(Magick::TransparentVirtualPixelMethod); image.virtualPixelMethod(Magick::TransparentVirtualPixelMethod);
image.backgroundColor("none"); image.backgroundColor("none");
image.scale(Geometry("365x179!")); image.scale(Geometry("365x179!"));
double arguments[16] = {0, 0, 207, 268, 365, 0, 548, 271, double arguments[16] = {0, 0, 207, 268, 365, 0, 548, 271,
365, 179, 558, 450, 0, 179, 193, 450}; 365, 179, 558, 450, 0, 179, 193, 450};
image.distort(Magick::PerspectiveDistortion, 16, arguments, true); image.distort(Magick::PerspectiveDistortion, 16, arguments, true);
image.extent(Geometry("800x450"), Magick::CenterGravity); image.extent(Geometry("800x450"), Magick::CenterGravity);
watermark_new.composite(image, Geometry("-25+134"), watermark_new.composite(image, Geometry("-25+134"),
Magick::DstOverCompositeOp); Magick::DstOverCompositeOp);
watermark_new.magick(type); watermark_new.magick(type);
watermark_new.animationDelay(delay == 0 ? image.animationDelay() : delay); watermark_new.animationDelay(delay == 0 ? image.animationDelay() : delay);
mid.push_back(watermark_new); mid.push_back(watermark_new);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
} }
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,49 +9,53 @@ using namespace Magick;
Napi::Value Wall(const Napi::CallbackInfo &info) { Napi::Value Wall(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
readImages(&frames, path); readImages(&frames, path);
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
image.resize(Geometry("128x128")); image.resize(Geometry("128x128"));
image.virtualPixelMethod(Magick::TileVirtualPixelMethod); image.virtualPixelMethod(Magick::TileVirtualPixelMethod);
image.matteColor("none"); image.matteColor("none");
image.backgroundColor("none"); image.backgroundColor("none");
image.scale(Geometry("512x512")); image.scale(Geometry("512x512"));
double arguments[16] = {0, 0, 57, 42, 0, 128, 63, 130, double arguments[16] = {0, 0, 57, 42, 0, 128, 63, 130,
128, 0, 140, 60, 128, 128, 140, 140}; 128, 0, 140, 60, 128, 128, 140, 140};
image.distort(Magick::PerspectiveDistortion, 16, arguments); image.distort(Magick::PerspectiveDistortion, 16, arguments);
image.scale(Geometry("800x800>")); image.scale(Geometry("800x800>"));
image.magick(type); image.magick(type);
mid.push_back(image); mid.push_back(image);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
if (delay != 0) image.animationDelay(delay);
} }
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
if (delay != 0) image.animationDelay(delay);
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -10,74 +10,80 @@ using namespace Magick;
Napi::Value Watermark(const Napi::CallbackInfo &info) { Napi::Value Watermark(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string water = obj.Get("water").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int gravity = obj.Get("gravity").As<Napi::Number>().Int32Value(); string water = obj.Get("water").As<Napi::String>().Utf8Value();
bool resize = int gravity = obj.Get("gravity").As<Napi::Number>().Int32Value();
obj.Has("resize") ? obj.Get("resize").As<Napi::Boolean>().Value() : false; bool resize = obj.Has("resize")
bool append = ? obj.Get("resize").As<Napi::Boolean>().Value()
obj.Has("append") ? obj.Get("append").As<Napi::Boolean>().Value() : false; : false;
bool mc = obj.Has("mc") ? obj.Get("mc").As<Napi::Boolean>().Value() : false; bool append = obj.Has("append")
string type = obj.Get("type").As<Napi::String>().Utf8Value(); ? obj.Get("append").As<Napi::Boolean>().Value()
int delay = : false;
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; bool mc = obj.Has("mc") ? obj.Get("mc").As<Napi::Boolean>().Value() : false;
string type = obj.Get("type").As<Napi::String>().Utf8Value();
int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
Image watermark; Image watermark;
readImages(&frames, path); readImages(&frames, path);
watermark.read(water); watermark.read(water);
if (resize && append) { if (resize && append) {
string query(to_string(frames.front().baseColumns()) + "x"); string query(to_string(frames.front().baseColumns()) + "x");
watermark.scale(Geometry(query)); watermark.scale(Geometry(query));
} else if (resize) { } else if (resize) {
string query("x" + to_string(frames.front().baseRows())); string query("x" + to_string(frames.front().baseRows()));
watermark.scale(Geometry(query)); watermark.scale(Geometry(query));
}
coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) {
Image final;
if (append) {
list<Image> to_append;
to_append.push_back(image);
to_append.push_back(watermark);
appendImages(&final, to_append.begin(), to_append.end(), true);
final.repage();
} else if (mc) {
image.backgroundColor("white");
image.extent(Geometry(image.columns(), image.rows() + 15));
image.composite(watermark, Magick::GravityType(gravity),
Magick::OverCompositeOp);
final = image;
} else {
image.composite(watermark, Magick::GravityType(gravity),
Magick::OverCompositeOp);
final = image;
} }
image.magick(type); coalesceImages(&coalesced, frames.begin(), frames.end());
final.animationDelay(delay == 0 ? image.animationDelay() : delay);
mid.push_back(final);
}
optimizeTransparency(mid.begin(), mid.end()); for (Image &image : coalesced) {
Image final;
if (type == "gif") { if (append) {
for (Image &image : mid) { list<Image> to_append;
image.quantizeDitherMethod(FloydSteinbergDitherMethod); to_append.push_back(image);
image.quantize(); to_append.push_back(watermark);
appendImages(&final, to_append.begin(), to_append.end(), true);
final.repage();
} else if (mc) {
image.backgroundColor("white");
image.extent(Geometry(image.columns(), image.rows() + 15));
image.composite(watermark, Magick::GravityType(gravity),
Magick::OverCompositeOp);
final = image;
} else {
image.composite(watermark, Magick::GravityType(gravity),
Magick::OverCompositeOp);
final = image;
}
image.magick(type);
final.animationDelay(delay == 0 ? image.animationDelay() : delay);
mid.push_back(final);
} }
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }

View File

@ -9,46 +9,50 @@ using namespace Magick;
Napi::Value Wdt(const Napi::CallbackInfo &info) { Napi::Value Wdt(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env(); Napi::Env env = info.Env();
Napi::Object obj = info[0].As<Napi::Object>(); try {
string path = obj.Get("path").As<Napi::String>().Utf8Value(); Napi::Object obj = info[0].As<Napi::Object>();
string type = obj.Get("type").As<Napi::String>().Utf8Value(); string path = obj.Get("path").As<Napi::String>().Utf8Value();
int delay = string type = obj.Get("type").As<Napi::String>().Utf8Value();
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0; int delay =
obj.Has("delay") ? obj.Get("delay").As<Napi::Number>().Int32Value() : 0;
Blob blob; Blob blob;
list<Image> frames; list<Image> frames;
list<Image> coalesced; list<Image> coalesced;
list<Image> mid; list<Image> mid;
Image watermark; Image watermark;
readImages(&frames, path); readImages(&frames, path);
watermark.read("./assets/images/whodidthis.png"); watermark.read("./assets/images/whodidthis.png");
coalesceImages(&coalesced, frames.begin(), frames.end()); coalesceImages(&coalesced, frames.begin(), frames.end());
for (Image &image : coalesced) { for (Image &image : coalesced) {
Image watermark_new = watermark; Image watermark_new = watermark;
image.scale(Geometry("374x374>")); image.scale(Geometry("374x374>"));
watermark_new.composite(image, Magick::CenterGravity, watermark_new.composite(image, Magick::CenterGravity,
Magick::OverCompositeOp); Magick::OverCompositeOp);
watermark_new.magick(type); watermark_new.magick(type);
watermark_new.animationDelay(delay == 0 ? image.animationDelay() : delay); watermark_new.animationDelay(delay == 0 ? image.animationDelay() : delay);
mid.push_back(watermark_new); mid.push_back(watermark_new);
}
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
} }
optimizeTransparency(mid.begin(), mid.end());
if (type == "gif") {
for (Image &image : mid) {
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
image.quantize();
}
}
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
blob.length()));
result.Set("type", type);
return result;
} catch (std::exception const &err) {
throw Napi::Error::New(env, err.what());
} }
writeImages(mid.begin(), mid.end(), &blob);
Napi::Object result = Napi::Object::New(env);
result.Set("data",
Napi::Buffer<char>::Copy(env, (char *)blob.data(), blob.length()));
result.Set("type", type);
return result;
} }