Finish converting natives
This commit is contained in:
parent
e1a31d6ddc
commit
47b2d9fcff
72 changed files with 746 additions and 876 deletions
|
@ -7,14 +7,14 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Blur(string type, char *BufferData, size_t BufferLength,
|
||||
char *Blur(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
bool sharp = GetArgument<bool>(Arguments, "sharp");
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
|
||||
if (!in.has_alpha())
|
||||
|
@ -26,7 +26,7 @@ char *Blur(string type, char *BufferData, size_t BufferLength,
|
|||
sharp ? in.sharpen(VImage::option()->set("sigma", 3)) : in.gaussblur(15);
|
||||
|
||||
void *buf;
|
||||
out.write_to_buffer(("." + type).c_str(), &buf, DataSize);
|
||||
out.write_to_buffer(("." + *type).c_str(), &buf, DataSize);
|
||||
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
using std::map;
|
||||
using std::string;
|
||||
|
||||
char* Blur(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Blur(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -7,7 +7,7 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Caption(string type, char *BufferData, size_t BufferLength,
|
||||
char *Caption(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
string caption = GetArgument<string>(Arguments, "caption");
|
||||
|
@ -18,7 +18,7 @@ char *Caption(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
|
||||
if (!in.has_alpha())
|
||||
|
@ -60,7 +60,7 @@ char *Caption(string type, char *BufferData, size_t BufferLength,
|
|||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
VImage frame = captionImage.join(
|
||||
img_frame, VIPS_DIRECTION_VERTICAL,
|
||||
VImage::option()->set("background", 0xffffff)->set("expand", true));
|
||||
|
@ -71,8 +71,8 @@ char *Caption(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
void *buf;
|
||||
final.write_to_buffer(
|
||||
("." + type).c_str(), &buf, DataSize,
|
||||
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
vips_error_clear();
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
using std::map;
|
||||
using std::string;
|
||||
|
||||
char* Caption(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Caption(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -7,7 +7,7 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *CaptionTwo(string type, char *BufferData, size_t BufferLength,
|
||||
char *CaptionTwo(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
bool top = GetArgument<bool>(Arguments, "top");
|
||||
|
@ -19,7 +19,7 @@ char *CaptionTwo(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
|
||||
if (!in.has_alpha())
|
||||
|
@ -60,7 +60,7 @@ char *CaptionTwo(string type, char *BufferData, size_t BufferLength,
|
|||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
VImage frame =
|
||||
(top ? captionImage : img_frame)
|
||||
.join(top ? img_frame : captionImage, VIPS_DIRECTION_VERTICAL,
|
||||
|
@ -74,8 +74,8 @@ char *CaptionTwo(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
void *buf;
|
||||
final.write_to_buffer(
|
||||
("." + type).c_str(), &buf, DataSize,
|
||||
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
vips_error_clear();
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
using std::map;
|
||||
using std::string;
|
||||
|
||||
char* CaptionTwo(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* CaptionTwo(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -10,7 +10,7 @@
|
|||
using namespace std;
|
||||
using namespace Magick;
|
||||
|
||||
char *Circle(string type, char *BufferData, size_t BufferLength,
|
||||
char *Circle(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
Blob blob;
|
||||
|
@ -29,13 +29,13 @@ char *Circle(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
for (Image &image : coalesced) {
|
||||
image.rotationalBlur(10);
|
||||
image.magick(type);
|
||||
image.magick(*type);
|
||||
blurred.push_back(image);
|
||||
}
|
||||
|
||||
optimizeTransparency(blurred.begin(), blurred.end());
|
||||
|
||||
if (type == "gif") {
|
||||
if (*type == "gif") {
|
||||
for (Image &image : blurred) {
|
||||
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
||||
image.quantize();
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
using std::map;
|
||||
using std::string;
|
||||
|
||||
char* Circle(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Circle(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -10,7 +10,7 @@ using namespace vips;
|
|||
VImage sepia = VImage::new_matrixv(3, 3, 0.3588, 0.7044, 0.1368, 0.2990, 0.5870,
|
||||
0.1140, 0.2392, 0.4696, 0.0912);
|
||||
|
||||
char *Colors(string type, char *BufferData, size_t BufferLength,
|
||||
char *Colors(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
string color = GetArgument<string>(Arguments, "color");
|
||||
|
@ -19,7 +19,7 @@ char *Colors(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
|
||||
VImage out;
|
||||
|
@ -31,7 +31,7 @@ char *Colors(string type, char *BufferData, size_t BufferLength,
|
|||
}
|
||||
|
||||
void *buf;
|
||||
out.write_to_buffer(("." + type).c_str(), &buf, DataSize);
|
||||
out.write_to_buffer(("." + *type).c_str(), &buf, DataSize);
|
||||
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
using std::map;
|
||||
using std::string;
|
||||
|
||||
char* Colors(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Colors(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -6,14 +6,14 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Crop(string type, char *BufferData, size_t BufferLength,
|
||||
char *Crop(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
|
||||
int width = in.width();
|
||||
|
@ -24,7 +24,7 @@ char *Crop(string type, char *BufferData, size_t BufferLength,
|
|||
int finalHeight = 0;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
int frameWidth = img_frame.width();
|
||||
int frameHeight = img_frame.height();
|
||||
bool widthOrHeight = frameWidth / frameHeight >= 1;
|
||||
|
@ -42,8 +42,8 @@ char *Crop(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
void *buf;
|
||||
final.write_to_buffer(
|
||||
("." + type).c_str(), &buf, DataSize,
|
||||
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
vips_error_clear();
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
using std::map;
|
||||
using std::string;
|
||||
|
||||
char* Crop(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Crop(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,14 +5,14 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Deepfry(string type, char *BufferData, size_t BufferLength,
|
||||
char *Deepfry(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
|
||||
if (!in.has_alpha())
|
||||
|
@ -26,7 +26,7 @@ char *Deepfry(string type, char *BufferData, size_t BufferLength,
|
|||
VImage fried = (in * 1.3 - (255.0 * 1.3 - 255.0)) * 1.5;
|
||||
|
||||
VImage final;
|
||||
if (totalHeight > 65500 && type == "gif") {
|
||||
if (totalHeight > 65500 && *type == "gif") {
|
||||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame = in.crop(0, i * pageHeight, width, pageHeight);
|
||||
|
@ -49,13 +49,13 @@ char *Deepfry(string type, char *BufferData, size_t BufferLength,
|
|||
VImage::option()->set("Q", 1)->set("strip", true));
|
||||
final = VImage::new_from_buffer(jpgBuf, jpgLength, "");
|
||||
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
|
||||
if (type == "gif")
|
||||
if (*type == "gif")
|
||||
final.set("delay", fried.get_array_int("delay"));
|
||||
}
|
||||
|
||||
void *buf;
|
||||
final.write_to_buffer(("." + type).c_str(), &buf, DataSize,
|
||||
type == "gif" ? VImage::option()->set("dither", 0) : 0);
|
||||
final.write_to_buffer(("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("dither", 0) : 0);
|
||||
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
using std::map;
|
||||
using std::string;
|
||||
|
||||
char* Deepfry(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Deepfry(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -11,7 +11,7 @@
|
|||
using namespace std;
|
||||
using namespace Magick;
|
||||
|
||||
char *Explode(string type, char *BufferData, size_t BufferLength,
|
||||
char *Explode(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
int amount = GetArgument<int>(Arguments, "amount");
|
||||
|
@ -33,13 +33,13 @@ char *Explode(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
for (Image &image : coalesced) {
|
||||
image.implode(amount);
|
||||
image.magick(type);
|
||||
image.magick(*type);
|
||||
blurred.push_back(image);
|
||||
}
|
||||
|
||||
optimizeTransparency(blurred.begin(), blurred.end());
|
||||
|
||||
if (type == "gif") {
|
||||
if (*type == "gif") {
|
||||
for (Image &image : blurred) {
|
||||
image.quantizeDither(false);
|
||||
image.quantize();
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
using std::map;
|
||||
using std::string;
|
||||
|
||||
char* Explode(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Explode(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -7,7 +7,7 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Flag(string type, char *BufferData, size_t BufferLength,
|
||||
char *Flag(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
string overlay = GetArgument<string>(Arguments, "overlay");
|
||||
|
@ -17,7 +17,7 @@ char *Flag(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
|
||||
if (!in.has_alpha())
|
||||
|
@ -43,7 +43,7 @@ char *Flag(string type, char *BufferData, size_t BufferLength,
|
|||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
VImage composited =
|
||||
img_frame.composite2(overlayImage, VIPS_BLEND_MODE_OVER);
|
||||
img.push_back(composited);
|
||||
|
@ -54,8 +54,8 @@ char *Flag(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
void *buf;
|
||||
final.write_to_buffer(
|
||||
("." + type).c_str(), &buf, DataSize,
|
||||
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
vips_error_clear();
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
using std::map;
|
||||
using std::string;
|
||||
|
||||
char* Flag(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Flag(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -7,13 +7,13 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Flip(string type, char *BufferData, size_t BufferLength,
|
||||
char *Flip(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
bool flop = GetArgument<bool>(Arguments, "flop");
|
||||
|
||||
VImage in = VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif"
|
||||
*type == "gif"
|
||||
? VImage::option()->set("n", -1)->set(
|
||||
"access", "sequential")
|
||||
: 0)
|
||||
|
@ -24,7 +24,7 @@ char *Flip(string type, char *BufferData, size_t BufferLength,
|
|||
VImage out;
|
||||
if (flop) {
|
||||
out = in.flip(VIPS_DIRECTION_HORIZONTAL);
|
||||
} else if (type == "gif") {
|
||||
} else if (*type == "gif") {
|
||||
// libvips gif handling is both a blessing and a curse
|
||||
vector<VImage> img;
|
||||
int pageHeight = vips_image_get_page_height(in.get_image());
|
||||
|
@ -42,8 +42,8 @@ char *Flip(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
void *buf;
|
||||
out.write_to_buffer(
|
||||
("." + type).c_str(), &buf, DataSize,
|
||||
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
vips_error_clear();
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
using std::map;
|
||||
using std::string;
|
||||
|
||||
char* Flip(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Flip(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -8,7 +8,7 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Freeze(string type, char *BufferData, size_t BufferLength,
|
||||
char *Freeze(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
bool loop = GetArgumentWithFallback<bool>(Arguments, "loop", false);
|
||||
|
@ -54,7 +54,7 @@ char *Freeze(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
in = in.bandjoin(255);
|
||||
|
@ -67,7 +67,7 @@ char *Freeze(string type, char *BufferData, size_t BufferLength,
|
|||
out.set("loop", 1);
|
||||
|
||||
void *buf;
|
||||
out.write_to_buffer(("." + type).c_str(), &buf, DataSize);
|
||||
out.write_to_buffer(("." + *type).c_str(), &buf, DataSize);
|
||||
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
char* Freeze(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Freeze(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,7 +5,7 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Gamexplain(string type, char *BufferData, size_t BufferLength,
|
||||
char *Gamexplain(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||
|
@ -14,7 +14,7 @@ char *Gamexplain(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
in = in.bandjoin(255);
|
||||
|
@ -29,7 +29,7 @@ char *Gamexplain(string type, char *BufferData, size_t BufferLength,
|
|||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
VImage resized =
|
||||
img_frame
|
||||
.resize(1181.0 / (double)width,
|
||||
|
@ -43,8 +43,8 @@ char *Gamexplain(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
void *buf;
|
||||
final.write_to_buffer(
|
||||
("." + type).c_str(), &buf, DataSize,
|
||||
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
vips_error_clear();
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
char* Gamexplain(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Gamexplain(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,7 +5,7 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Globe(string type, char *BufferData, size_t BufferLength,
|
||||
char *Globe(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||
|
@ -15,7 +15,7 @@ char *Globe(string type, char *BufferData, size_t BufferLength,
|
|||
VImage in =
|
||||
VImage::new_from_buffer(
|
||||
BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1)->set("access", "sequential")
|
||||
*type == "gif" ? options->set("n", -1)->set("access", "sequential")
|
||||
: options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
|
@ -23,7 +23,7 @@ char *Globe(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
int width = in.width();
|
||||
int pageHeight = vips_image_get_page_height(in.get_image());
|
||||
int nPages = type == "gif" ? vips_image_get_n_pages(in.get_image()) : 30;
|
||||
int nPages = *type == "gif" ? vips_image_get_n_pages(in.get_image()) : 30;
|
||||
|
||||
double size = min(width, pageHeight);
|
||||
|
||||
|
@ -51,7 +51,7 @@ char *Globe(string type, char *BufferData, size_t BufferLength,
|
|||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
VImage resized = img_frame.resize(
|
||||
size / (double)width,
|
||||
VImage::option()->set("vscale", size / (double)pageHeight));
|
||||
|
@ -65,7 +65,7 @@ char *Globe(string type, char *BufferData, size_t BufferLength,
|
|||
}
|
||||
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
|
||||
final.set(VIPS_META_PAGE_HEIGHT, size);
|
||||
if (type != "gif") {
|
||||
if (*type != "gif") {
|
||||
vector<int> delay(30, 50);
|
||||
final.set("delay", delay);
|
||||
}
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
char* Globe(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Globe(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -51,7 +51,7 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
std::map<std::string, char* (*)(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize)> FunctionMap = {
|
||||
std::map<std::string, char* (*)(string *type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize)> FunctionMap = {
|
||||
{"blur", &Blur},
|
||||
{"caption", &Caption},
|
||||
{"captionTwo", &CaptionTwo},
|
||||
|
@ -67,36 +67,33 @@ std::map<std::string, char* (*)(string type, char* BufferData, size_t BufferLeng
|
|||
{"globe", Globe},
|
||||
{"invert", Invert},
|
||||
{"jpeg", Jpeg},
|
||||
{"magik", Magik},
|
||||
{"meme", Meme},
|
||||
{"mirror", Mirror},
|
||||
{"motivate", Motivate},
|
||||
{"reddit", Reddit},
|
||||
{"resize", Resize},
|
||||
{"reverse", Reverse},
|
||||
{"speed", &Speed},
|
||||
{"uncaption", &Uncaption},
|
||||
{"watermark", &Watermark}
|
||||
};
|
||||
|
||||
std::map<std::string, char* (*)(string *type, ArgumentMap Arguments, size_t* DataSize)> NoInputFunctionMap = {
|
||||
{"homebrew", Homebrew},
|
||||
{"sonic", Sonic}
|
||||
};
|
||||
|
||||
std::map<std::string, Napi::Value (*)(const Napi::CallbackInfo &info)> OldFunctionMap = {
|
||||
{"magik", Magik},
|
||||
{"scott", Scott},
|
||||
{"snapchat", Snapchat},
|
||||
{"speed", &Speed},
|
||||
{"spin", Spin},
|
||||
{"swirl", Swirl},
|
||||
{"tile", Tile},
|
||||
{"togif", ToGif},
|
||||
{"uncanny", Uncanny},
|
||||
{"uncaption", &Uncaption},
|
||||
{"wall", Wall},
|
||||
{"watermark", &Watermark},
|
||||
{"whisper", Whisper},
|
||||
{"zamn", Zamn}
|
||||
};
|
||||
|
||||
std::map<std::string, char* (*)(string *type, ArgumentMap Arguments, size_t* DataSize)> NoInputFunctionMap = {
|
||||
{"homebrew", Homebrew},
|
||||
{"sonic", Sonic}
|
||||
};
|
||||
|
||||
bool isNapiValueInt(Napi::Env& env, Napi::Value& num) {
|
||||
return env.Global()
|
||||
.Get("Number")
|
||||
|
@ -150,7 +147,7 @@ Napi::Value NewProcessImage(const Napi::CallbackInfo &info, bool input) {
|
|||
char* buf;
|
||||
if (input) {
|
||||
Napi::Buffer<char> data = obj.Has("data") ? obj.Get("data").As<Napi::Buffer<char>>() : Napi::Buffer<char>::New(env, 0);
|
||||
buf = FunctionMap.at(command)(type, data.Data(), data.Length(), Arguments, &length);
|
||||
buf = FunctionMap.at(command)(&type, data.Data(), data.Length(), Arguments, &length);
|
||||
} else {
|
||||
buf = NoInputFunctionMap.at(command)(&type, Arguments, &length);
|
||||
}
|
||||
|
@ -167,10 +164,6 @@ Napi::Value NewProcessImage(const Napi::CallbackInfo &info, bool input) {
|
|||
return result;
|
||||
}
|
||||
|
||||
Napi::Value OldProcessImage(std::string FunctionName, const Napi::CallbackInfo &info) {
|
||||
return OldFunctionMap.at(FunctionName)(info);
|
||||
}
|
||||
|
||||
Napi::Value ProcessImage(const Napi::CallbackInfo &info) { // janky solution for gradual adoption
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
|
@ -180,8 +173,6 @@ Napi::Value ProcessImage(const Napi::CallbackInfo &info) { // janky solution for
|
|||
return NewProcessImage(info, true);
|
||||
} else if (MAP_HAS(NoInputFunctionMap, command)) {
|
||||
return NewProcessImage(info, false);
|
||||
} else if (MAP_HAS(OldFunctionMap, command)) {
|
||||
return OldProcessImage(command, info);
|
||||
} else {
|
||||
Napi::Error::New(env, "Invalid command").ThrowAsJavaScriptException();
|
||||
return env.Null();
|
||||
|
@ -208,11 +199,6 @@ Napi::Object Init(Napi::Env env, Napi::Object exports){
|
|||
arr[i] = Napi::String::New(env, imap.first);
|
||||
i++;
|
||||
}
|
||||
for(auto const& imap: OldFunctionMap) {
|
||||
Napi::HandleScope scope(env);
|
||||
arr[i] = Napi::String::New(env, imap.first);
|
||||
i++;
|
||||
}
|
||||
|
||||
exports.Set(Napi::String::New(env, "funcs"), arr);
|
||||
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Invert(string type, char *BufferData, size_t BufferLength,
|
||||
char *Invert(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
in = in.bandjoin(255);
|
||||
|
@ -23,7 +23,7 @@ char *Invert(string type, char *BufferData, size_t BufferLength,
|
|||
VImage out = inverted.bandjoin(in.extract_band(3));
|
||||
|
||||
void *buf;
|
||||
out.write_to_buffer(("." + type).c_str(), &buf, DataSize);
|
||||
out.write_to_buffer(("." + *type).c_str(), &buf, DataSize);
|
||||
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
char* Invert(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Invert(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,13 +5,13 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Jpeg(string type, char *BufferData, size_t BufferLength,
|
||||
char *Jpeg(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
int quality = GetArgumentWithFallback<int>(Arguments, "quality", 0);
|
||||
|
||||
void *buf;
|
||||
|
||||
if (type == "gif") {
|
||||
if (*type == "gif") {
|
||||
VImage in = VImage::new_from_buffer(
|
||||
BufferData, BufferLength, "",
|
||||
VImage::option()->set("access", "sequential")->set("n", -1))
|
||||
|
@ -53,15 +53,15 @@ char *Jpeg(string type, char *BufferData, size_t BufferLength,
|
|||
final.set("delay", in.get_array_int("delay"));
|
||||
}
|
||||
|
||||
final.write_to_buffer(("." + type).c_str(), &buf, DataSize,
|
||||
type == "gif" ? VImage::option()->set("dither", 0)
|
||||
final.write_to_buffer(("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("dither", 0)
|
||||
: 0);
|
||||
} else {
|
||||
VImage in = VImage::new_from_buffer(BufferData, BufferLength, "");
|
||||
in.write_to_buffer(".jpg", &buf, DataSize,
|
||||
VImage::option()->set("Q", quality)->set("strip", true));
|
||||
|
||||
type = "jpg";
|
||||
*type = "jpg";
|
||||
}
|
||||
|
||||
vips_error_clear();
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
char* Jpeg(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Jpeg(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -1,62 +1,52 @@
|
|||
#include "common.h"
|
||||
#include <Magick++.h>
|
||||
#include <napi.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
|
||||
using namespace std;
|
||||
using namespace Magick;
|
||||
|
||||
Napi::Value Magik(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::Object result = Napi::Object::New(env);
|
||||
char *Magik(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
Blob blob;
|
||||
|
||||
list<Image> frames;
|
||||
list<Image> coalesced;
|
||||
list<Image> blurred;
|
||||
try {
|
||||
Napi::Object obj = info[1].As<Napi::Object>();
|
||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||
readImages(&frames, Blob(BufferData, BufferLength));
|
||||
} catch (Magick::WarningCoder &warning) {
|
||||
cerr << "Coder Warning: " << warning.what() << endl;
|
||||
} catch (Magick::Warning &warning) {
|
||||
cerr << "Warning: " << warning.what() << endl;
|
||||
}
|
||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||
|
||||
Blob blob;
|
||||
|
||||
list<Image> frames;
|
||||
list<Image> coalesced;
|
||||
list<Image> blurred;
|
||||
try {
|
||||
readImages(&frames, Blob(data.Data(), data.Length()));
|
||||
} catch (Magick::WarningCoder &warning) {
|
||||
cerr << "Coder Warning: " << warning.what() << endl;
|
||||
} catch (Magick::Warning &warning) {
|
||||
cerr << "Warning: " << warning.what() << endl;
|
||||
}
|
||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||
|
||||
for (Image &image : coalesced) {
|
||||
image.scale(Geometry("350x350"));
|
||||
image.liquidRescale(Geometry("175x175"));
|
||||
image.liquidRescale(Geometry("350x350"));
|
||||
image.magick(type);
|
||||
blurred.push_back(image);
|
||||
}
|
||||
|
||||
optimizeTransparency(blurred.begin(), blurred.end());
|
||||
|
||||
if (type == "gif") {
|
||||
for (Image &image : blurred) {
|
||||
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
||||
image.quantize();
|
||||
}
|
||||
}
|
||||
|
||||
writeImages(blurred.begin(), blurred.end(), &blob);
|
||||
|
||||
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
|
||||
blob.length()));
|
||||
result.Set("type", type);
|
||||
} catch (std::exception const &err) {
|
||||
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
|
||||
} catch (...) {
|
||||
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
|
||||
for (Image &image : coalesced) {
|
||||
image.scale(Geometry("350x350"));
|
||||
image.liquidRescale(Geometry("175x175"));
|
||||
image.liquidRescale(Geometry("350x350"));
|
||||
image.magick(*type);
|
||||
blurred.push_back(image);
|
||||
}
|
||||
|
||||
return result;
|
||||
optimizeTransparency(blurred.begin(), blurred.end());
|
||||
|
||||
if (*type == "gif") {
|
||||
for (Image &image : blurred) {
|
||||
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
||||
image.quantize();
|
||||
}
|
||||
}
|
||||
|
||||
writeImages(blurred.begin(), blurred.end(), &blob);
|
||||
|
||||
*DataSize = blob.length();
|
||||
|
||||
char *data = (char *)malloc(*DataSize);
|
||||
memcpy(data, blob.data(), *DataSize);
|
||||
return data;
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
Napi::Value Magik(const Napi::CallbackInfo& info);
|
||||
using std::string;
|
||||
|
||||
char* Magik(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,7 +5,7 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Meme(string type, char *BufferData, size_t BufferLength,
|
||||
char *Meme(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
string top = GetArgument<string>(Arguments, "top");
|
||||
string bottom = GetArgument<string>(Arguments, "bottom");
|
||||
|
@ -16,7 +16,7 @@ char *Meme(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
in = in.bandjoin(255);
|
||||
|
@ -112,7 +112,7 @@ char *Meme(string type, char *BufferData, size_t BufferLength,
|
|||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
if (top != "") {
|
||||
img_frame = img_frame.composite2(
|
||||
topText, VIPS_BLEND_MODE_OVER,
|
||||
|
@ -132,8 +132,8 @@ char *Meme(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
void *buf;
|
||||
final.write_to_buffer(
|
||||
("." + type).c_str(), &buf, DataSize,
|
||||
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
vips_error_clear();
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
char* Meme(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Meme(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,7 +5,7 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Mirror(string type, char *BufferData, size_t BufferLength,
|
||||
char *Mirror(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
bool vertical = GetArgumentWithFallback<bool>(Arguments, "vertical", false);
|
||||
bool first = GetArgumentWithFallback<bool>(Arguments, "first", false);
|
||||
|
@ -14,7 +14,7 @@ char *Mirror(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
in = in.bandjoin(255);
|
||||
|
@ -22,7 +22,7 @@ char *Mirror(string type, char *BufferData, size_t BufferLength,
|
|||
VImage out;
|
||||
|
||||
if (vertical) {
|
||||
if (type == "gif") {
|
||||
if (*type == "gif") {
|
||||
// once again, libvips gif handling is both a blessing and a curse
|
||||
vector<VImage> img;
|
||||
int pageHeight = vips_image_get_page_height(in.get_image());
|
||||
|
@ -59,7 +59,7 @@ char *Mirror(string type, char *BufferData, size_t BufferLength,
|
|||
}
|
||||
|
||||
void *buf;
|
||||
out.write_to_buffer(("." + type).c_str(), &buf, DataSize);
|
||||
out.write_to_buffer(("." + *type).c_str(), &buf, DataSize);
|
||||
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
char* Mirror(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Mirror(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,7 +5,7 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Motivate(string type, char *BufferData, size_t BufferLength,
|
||||
char *Motivate(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
string top_text = GetArgument<string>(Arguments, "top");
|
||||
string bottom_text = GetArgument<string>(Arguments, "bottom");
|
||||
|
@ -16,7 +16,7 @@ char *Motivate(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
in = in.bandjoin(255);
|
||||
|
@ -70,7 +70,7 @@ char *Motivate(string type, char *BufferData, size_t BufferLength,
|
|||
int height;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
|
||||
int borderSize = max(2, width / 66);
|
||||
int borderSize2 = borderSize * 0.5;
|
||||
|
@ -117,8 +117,8 @@ char *Motivate(string type, char *BufferData, size_t BufferLength,
|
|||
final.set(VIPS_META_PAGE_HEIGHT, height);
|
||||
|
||||
void *buf;
|
||||
final.write_to_buffer(("." + type).c_str(), &buf, DataSize,
|
||||
type == "gif" ? VImage::option()->set("dither", 1) : 0);
|
||||
final.write_to_buffer(("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("dither", 1) : 0);
|
||||
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
char* Motivate(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Motivate(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,7 +5,7 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Reddit(string type, char *BufferData, size_t BufferLength,
|
||||
char *Reddit(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
string text = GetArgument<string>(Arguments, "text");
|
||||
|
@ -15,7 +15,7 @@ char *Reddit(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
in = in.bandjoin(255);
|
||||
|
@ -50,7 +50,7 @@ char *Reddit(string type, char *BufferData, size_t BufferLength,
|
|||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
VImage frame = img_frame.join(watermark, VIPS_DIRECTION_VERTICAL,
|
||||
VImage::option()->set("expand", true));
|
||||
img.push_back(frame);
|
||||
|
@ -60,8 +60,8 @@ char *Reddit(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
void *buf;
|
||||
final.write_to_buffer(
|
||||
("." + type).c_str(), &buf, DataSize,
|
||||
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
vips_error_clear();
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
char* Reddit(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Reddit(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -5,7 +5,7 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Resize(string type, char *BufferData, size_t BufferLength,
|
||||
char *Resize(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
bool stretch = GetArgumentWithFallback<bool>(Arguments, "stretch", false);
|
||||
bool wide = GetArgumentWithFallback<bool>(Arguments, "wide", false);
|
||||
|
@ -14,7 +14,7 @@ char *Resize(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
|
||||
VImage out;
|
||||
|
@ -37,7 +37,7 @@ char *Resize(string type, char *BufferData, size_t BufferLength,
|
|||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
VImage resized = img_frame.resize(0.1).resize(
|
||||
10, VImage::option()->set("kernel", VIPS_KERNEL_NEAREST));
|
||||
img.push_back(resized);
|
||||
|
@ -48,7 +48,7 @@ char *Resize(string type, char *BufferData, size_t BufferLength,
|
|||
out.set(VIPS_META_PAGE_HEIGHT, finalHeight);
|
||||
|
||||
void *buf;
|
||||
out.write_to_buffer(("." + type).c_str(), &buf, DataSize);
|
||||
out.write_to_buffer(("." + *type).c_str(), &buf, DataSize);
|
||||
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
char* Resize(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Resize(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -6,7 +6,7 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Reverse(string type, char *BufferData, size_t BufferLength,
|
||||
char *Reverse(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
bool soos = GetArgumentWithFallback<bool>(Arguments, "soos", false);
|
||||
|
||||
|
@ -53,7 +53,7 @@ char *Reverse(string type, char *BufferData, size_t BufferLength,
|
|||
final.write_to_buffer(".gif", &buf, DataSize,
|
||||
VImage::option()->set("dither", 0));
|
||||
|
||||
type = "gif";
|
||||
*type = "gif";
|
||||
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
char* Reverse(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Reverse(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
108
natives/scott.cc
108
natives/scott.cc
|
@ -1,73 +1,63 @@
|
|||
#include "common.h"
|
||||
#include <Magick++.h>
|
||||
#include <napi.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
|
||||
using namespace std;
|
||||
using namespace Magick;
|
||||
|
||||
Napi::Value Scott(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::Object result = Napi::Object::New(env);
|
||||
char *Scott(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||
|
||||
Blob blob;
|
||||
|
||||
list<Image> frames;
|
||||
list<Image> coalesced;
|
||||
list<Image> mid;
|
||||
Image watermark;
|
||||
try {
|
||||
Napi::Object obj = info[1].As<Napi::Object>();
|
||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||
readImages(&frames, Blob(BufferData, BufferLength));
|
||||
} catch (Magick::WarningCoder &warning) {
|
||||
cerr << "Coder Warning: " << warning.what() << endl;
|
||||
} catch (Magick::Warning &warning) {
|
||||
cerr << "Warning: " << warning.what() << endl;
|
||||
}
|
||||
watermark.read(basePath + "assets/images/scott.png");
|
||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||
|
||||
Blob blob;
|
||||
|
||||
list<Image> frames;
|
||||
list<Image> coalesced;
|
||||
list<Image> mid;
|
||||
Image watermark;
|
||||
try {
|
||||
readImages(&frames, Blob(data.Data(), data.Length()));
|
||||
} catch (Magick::WarningCoder &warning) {
|
||||
cerr << "Coder Warning: " << warning.what() << endl;
|
||||
} catch (Magick::Warning &warning) {
|
||||
cerr << "Warning: " << warning.what() << endl;
|
||||
}
|
||||
watermark.read(basePath + "assets/images/scott.png");
|
||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||
|
||||
for (Image &image : coalesced) {
|
||||
Image watermark_new = watermark;
|
||||
image.virtualPixelMethod(Magick::TransparentVirtualPixelMethod);
|
||||
image.backgroundColor("none");
|
||||
image.scale(Geometry("415x234!"));
|
||||
double arguments[16] = {0, 0, 129, 187, 415, 0, 517, 182,
|
||||
415, 234, 517, 465, 0, 234, 132, 418};
|
||||
image.distort(Magick::PerspectiveDistortion, 16, arguments, true);
|
||||
image.extent(Geometry("864x481"), Magick::CenterGravity);
|
||||
watermark_new.composite(image, Geometry("-110+83"),
|
||||
Magick::OverCompositeOp);
|
||||
watermark_new.magick(type);
|
||||
watermark_new.animationDelay(image.animationDelay());
|
||||
mid.push_back(watermark_new);
|
||||
}
|
||||
|
||||
optimizeTransparency(mid.begin(), mid.end());
|
||||
|
||||
if (type == "gif") {
|
||||
for (Image &image : mid) {
|
||||
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
||||
image.quantize();
|
||||
}
|
||||
}
|
||||
|
||||
writeImages(mid.begin(), mid.end(), &blob);
|
||||
|
||||
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
|
||||
blob.length()));
|
||||
result.Set("type", type);
|
||||
} catch (std::exception const &err) {
|
||||
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
|
||||
} catch (...) {
|
||||
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
|
||||
for (Image &image : coalesced) {
|
||||
Image watermark_new = watermark;
|
||||
image.virtualPixelMethod(Magick::TransparentVirtualPixelMethod);
|
||||
image.backgroundColor("none");
|
||||
image.scale(Geometry("415x234!"));
|
||||
double arguments[16] = {0, 0, 129, 187, 415, 0, 517, 182,
|
||||
415, 234, 517, 465, 0, 234, 132, 418};
|
||||
image.distort(Magick::PerspectiveDistortion, 16, arguments, true);
|
||||
image.extent(Geometry("864x481"), Magick::CenterGravity);
|
||||
watermark_new.composite(image, Geometry("-110+83"),
|
||||
Magick::OverCompositeOp);
|
||||
watermark_new.magick(*type);
|
||||
watermark_new.animationDelay(image.animationDelay());
|
||||
mid.push_back(watermark_new);
|
||||
}
|
||||
|
||||
return result;
|
||||
optimizeTransparency(mid.begin(), mid.end());
|
||||
|
||||
if (*type == "gif") {
|
||||
for (Image &image : mid) {
|
||||
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
||||
image.quantize();
|
||||
}
|
||||
}
|
||||
|
||||
writeImages(mid.begin(), mid.end(), &blob);
|
||||
|
||||
*DataSize = blob.length();
|
||||
|
||||
char *data = (char *)malloc(*DataSize);
|
||||
memcpy(data, blob.data(), *DataSize);
|
||||
return data;
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
Napi::Value Scott(const Napi::CallbackInfo& info);
|
||||
using std::string;
|
||||
|
||||
char* Scott(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -1,92 +1,74 @@
|
|||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
#include <vips/vips8>
|
||||
|
||||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
Napi::Value Snapchat(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::Object result = Napi::Object::New(env);
|
||||
char *Snapchat(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
string caption = GetArgument<string>(Arguments, "caption");
|
||||
float pos = GetArgumentWithFallback<float>(Arguments, "pos", 0.5);
|
||||
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||
|
||||
try {
|
||||
Napi::Object obj = info[1].As<Napi::Object>();
|
||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||
string caption = obj.Get("caption").As<Napi::String>().Utf8Value();
|
||||
float pos =
|
||||
obj.Has("pos") ? obj.Get("pos").As<Napi::Number>().FloatValue() : 0.5;
|
||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
in = in.bandjoin(255);
|
||||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(data.Data(), data.Length(), "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
in = in.bandjoin(255);
|
||||
int width = in.width();
|
||||
int pageHeight = vips_image_get_page_height(in.get_image());
|
||||
int nPages = vips_image_get_n_pages(in.get_image());
|
||||
int size = width / 20;
|
||||
int textWidth = width - ((width / 25) * 2);
|
||||
|
||||
int width = in.width();
|
||||
int pageHeight = vips_image_get_page_height(in.get_image());
|
||||
int nPages = vips_image_get_n_pages(in.get_image());
|
||||
int size = width / 20;
|
||||
int textWidth = width - ((width / 25) * 2);
|
||||
string font_string = "Helvetica Neue, Twemoji Color Font " + to_string(size);
|
||||
|
||||
string font_string =
|
||||
"Helvetica Neue, Twemoji Color Font " + to_string(size);
|
||||
VImage textIn = VImage::text(
|
||||
".", VImage::option()->set(
|
||||
"fontfile", (basePath + "assets/fonts/caption2.ttf").c_str()));
|
||||
textIn = VImage::text(
|
||||
("<span foreground=\"white\" background=\"#000000B2\">" + caption +
|
||||
"</span>")
|
||||
.c_str(),
|
||||
VImage::option()
|
||||
->set("rgba", true)
|
||||
->set("align", VIPS_ALIGN_CENTRE)
|
||||
->set("font", font_string.c_str())
|
||||
->set("fontfile", (basePath + "assets/fonts/twemoji.otf").c_str())
|
||||
->set("width", textWidth));
|
||||
int bgHeight = textIn.height() + (width / 25);
|
||||
textIn = ((textIn == (vector<double>){0, 0, 0, 0}).bandand())
|
||||
.ifthenelse({0, 0, 0, 178}, textIn)
|
||||
.embed((width / 2) - (textIn.width() / 2),
|
||||
(bgHeight / 2) - (textIn.height() / 2), width, bgHeight,
|
||||
VImage::option()
|
||||
->set("extend", "background")
|
||||
->set("background", (vector<double>){0, 0, 0, 178}));
|
||||
|
||||
VImage textIn = VImage::text(
|
||||
".", VImage::option()->set(
|
||||
"fontfile", (basePath + "assets/fonts/caption2.ttf").c_str()));
|
||||
textIn = VImage::text(
|
||||
("<span foreground=\"white\" background=\"#000000B2\">" + caption +
|
||||
"</span>")
|
||||
.c_str(),
|
||||
VImage::option()
|
||||
->set("rgba", true)
|
||||
->set("align", VIPS_ALIGN_CENTRE)
|
||||
->set("font", font_string.c_str())
|
||||
->set("fontfile", (basePath + "assets/fonts/twemoji.otf").c_str())
|
||||
->set("width", textWidth));
|
||||
int bgHeight = textIn.height() + (width / 25);
|
||||
textIn =
|
||||
((textIn == (vector<double>){0, 0, 0, 0}).bandand())
|
||||
.ifthenelse({0, 0, 0, 178}, textIn)
|
||||
.embed((width / 2) - (textIn.width() / 2),
|
||||
(bgHeight / 2) - (textIn.height() / 2), width, bgHeight,
|
||||
VImage::option()
|
||||
->set("extend", "background")
|
||||
->set("background", (vector<double>){0, 0, 0, 178}));
|
||||
|
||||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
img_frame = img_frame.composite2(
|
||||
textIn, VIPS_BLEND_MODE_OVER,
|
||||
VImage::option()->set("x", 0)->set("y", pageHeight * pos));
|
||||
img.push_back(img_frame);
|
||||
}
|
||||
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
|
||||
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
|
||||
|
||||
void *buf;
|
||||
size_t length;
|
||||
final.write_to_buffer(
|
||||
("." + type).c_str(), &buf, &length,
|
||||
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length));
|
||||
result.Set("type", type);
|
||||
} catch (std::exception const &err) {
|
||||
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
|
||||
} catch (...) {
|
||||
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
|
||||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
img_frame = img_frame.composite2(
|
||||
textIn, VIPS_BLEND_MODE_OVER,
|
||||
VImage::option()->set("x", 0)->set("y", pageHeight * pos));
|
||||
img.push_back(img_frame);
|
||||
}
|
||||
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
|
||||
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
|
||||
|
||||
void *buf;
|
||||
final.write_to_buffer(
|
||||
("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
return result;
|
||||
return (char *)buf;
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
Napi::Value Snapchat(const Napi::CallbackInfo& info);
|
||||
using std::string;
|
||||
|
||||
char* Snapchat(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -42,7 +42,7 @@ char *vipsRemove(char *data, size_t length, size_t *DataSize, int speed) {
|
|||
return (char *)buf;
|
||||
}
|
||||
|
||||
char *Speed(string type, char *BufferData, size_t BufferLength,
|
||||
char *Speed(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
bool slow = GetArgumentWithFallback<bool>(Arguments, "slow", false);
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
char* Speed(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Speed(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
127
natives/spin.cc
127
natives/spin.cc
|
@ -1,80 +1,71 @@
|
|||
#include "common.h"
|
||||
#include <Magick++.h>
|
||||
#include <napi.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
|
||||
using namespace std;
|
||||
using namespace Magick;
|
||||
|
||||
Napi::Value Spin(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
char *Spin(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
int delay = GetArgumentWithFallback<int>(Arguments, "delay", 0);
|
||||
|
||||
Blob blob;
|
||||
|
||||
list<Image> frames;
|
||||
list<Image> coalesced;
|
||||
list<Image> mid;
|
||||
try {
|
||||
Napi::Object obj = info[1].As<Napi::Object>();
|
||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||
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;
|
||||
try {
|
||||
readImages(&frames, Blob(data.Data(), data.Length()));
|
||||
} catch (Magick::WarningCoder &warning) {
|
||||
cerr << "Coder Warning: " << warning.what() << endl;
|
||||
} catch (Magick::Warning &warning) {
|
||||
cerr << "Warning: " << warning.what() << endl;
|
||||
}
|
||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||
|
||||
if (type != "gif") {
|
||||
list<Image>::iterator it = coalesced.begin();
|
||||
for (int i = 0; i < 29; ++i) {
|
||||
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] = {(double)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());
|
||||
} catch (...) {
|
||||
throw Napi::Error::New(env, "Unknown error");
|
||||
readImages(&frames, Blob(BufferData, BufferLength));
|
||||
} catch (Magick::WarningCoder &warning) {
|
||||
cerr << "Coder Warning: " << warning.what() << endl;
|
||||
} catch (Magick::Warning &warning) {
|
||||
cerr << "Warning: " << warning.what() << endl;
|
||||
}
|
||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||
|
||||
if (*type != "gif") {
|
||||
list<Image>::iterator it = coalesced.begin();
|
||||
for (int i = 0; i < 29; ++i) {
|
||||
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] = {(double)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);
|
||||
|
||||
*type = "gif";
|
||||
*DataSize = blob.length();
|
||||
|
||||
char *data = (char *)malloc(*DataSize);
|
||||
memcpy(data, blob.data(), *DataSize);
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
Napi::Value Spin(const Napi::CallbackInfo& info);
|
||||
using std::string;
|
||||
|
||||
char* Spin(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
133
natives/swirl.cc
133
natives/swirl.cc
|
@ -1,95 +1,80 @@
|
|||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
#include <vips/vips8>
|
||||
|
||||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
Napi::Value Swirl(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::Object result = Napi::Object::New(env);
|
||||
char *Swirl(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
try {
|
||||
Napi::Object obj = info[1].As<Napi::Object>();
|
||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
in = in.bandjoin(255);
|
||||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(data.Data(), data.Length(), "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
in = in.bandjoin(255);
|
||||
int pageHeight = vips_image_get_page_height(in.get_image());
|
||||
int nPages = vips_image_get_n_pages(in.get_image());
|
||||
int width = in.width();
|
||||
double newWidth = width * 3;
|
||||
double newHeight = pageHeight * 3;
|
||||
vector<double> divSize = {newWidth / 2, newHeight / 2};
|
||||
|
||||
int pageHeight = vips_image_get_page_height(in.get_image());
|
||||
int nPages = vips_image_get_n_pages(in.get_image());
|
||||
int width = in.width();
|
||||
double newWidth = width * 3;
|
||||
double newHeight = pageHeight * 3;
|
||||
vector<double> divSize = {newWidth / 2, newHeight / 2};
|
||||
VImage index = VImage::xyz(newWidth, newHeight);
|
||||
VImage center = index - divSize;
|
||||
VImage polar = center
|
||||
.copy(VImage::option()
|
||||
->set("format", VIPS_FORMAT_COMPLEX)
|
||||
->set("bands", 1))
|
||||
.polar()
|
||||
.copy(VImage::option()
|
||||
->set("format", VIPS_FORMAT_FLOAT)
|
||||
->set("bands", 2));
|
||||
|
||||
VImage index = VImage::xyz(newWidth, newHeight);
|
||||
VImage center = index - divSize;
|
||||
VImage polar = center
|
||||
.copy(VImage::option()
|
||||
->set("format", VIPS_FORMAT_COMPLEX)
|
||||
->set("bands", 1))
|
||||
.polar()
|
||||
.copy(VImage::option()
|
||||
->set("format", VIPS_FORMAT_FLOAT)
|
||||
->set("bands", 2));
|
||||
int size = min(width, pageHeight) / 2;
|
||||
|
||||
int size = min(width, pageHeight) / 2;
|
||||
VImage test = (1 - polar.extract_band(0) / size);
|
||||
VImage degrees = test.cast(VIPS_FORMAT_FLOAT).pow(2);
|
||||
|
||||
VImage test = (1 - polar.extract_band(0) / size);
|
||||
VImage degrees = test.cast(VIPS_FORMAT_FLOAT).pow(2);
|
||||
VImage angle = polar.extract_band(1) + degrees * 180;
|
||||
|
||||
VImage angle = polar.extract_band(1) + degrees * 180;
|
||||
VImage distortion = polar.extract_band(0)
|
||||
.bandjoin(angle)
|
||||
.copy(VImage::option()
|
||||
->set("format", VIPS_FORMAT_COMPLEX)
|
||||
->set("bands", 1))
|
||||
.rect()
|
||||
.copy(VImage::option()
|
||||
->set("format", VIPS_FORMAT_FLOAT)
|
||||
->set("bands", 2)) +
|
||||
divSize;
|
||||
|
||||
VImage distortion = polar.extract_band(0)
|
||||
.bandjoin(angle)
|
||||
.copy(VImage::option()
|
||||
->set("format", VIPS_FORMAT_COMPLEX)
|
||||
->set("bands", 1))
|
||||
.rect()
|
||||
.copy(VImage::option()
|
||||
->set("format", VIPS_FORMAT_FLOAT)
|
||||
->set("bands", 2)) +
|
||||
divSize;
|
||||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
|
||||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
|
||||
VImage distort =
|
||||
img_frame
|
||||
.gravity(VIPS_COMPASS_DIRECTION_CENTRE, newWidth, newHeight,
|
||||
VImage::option()->set("extend", VIPS_EXTEND_COPY))
|
||||
.mapim(distortion, VImage::option()->set(
|
||||
"interpolate",
|
||||
VInterpolate::new_from_name("bicubic")));
|
||||
VImage frame = distort.crop(width, pageHeight, width, pageHeight);
|
||||
img.push_back(frame);
|
||||
}
|
||||
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
|
||||
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
|
||||
|
||||
void *buf;
|
||||
size_t length;
|
||||
final.write_to_buffer(".gif", &buf, &length);
|
||||
|
||||
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length));
|
||||
result.Set("type", type);
|
||||
} catch (std::exception const &err) {
|
||||
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
|
||||
} catch (...) {
|
||||
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
|
||||
VImage distort =
|
||||
img_frame
|
||||
.gravity(VIPS_COMPASS_DIRECTION_CENTRE, newWidth, newHeight,
|
||||
VImage::option()->set("extend", VIPS_EXTEND_COPY))
|
||||
.mapim(distortion,
|
||||
VImage::option()->set(
|
||||
"interpolate", VInterpolate::new_from_name("bicubic")));
|
||||
VImage frame = distort.crop(width, pageHeight, width, pageHeight);
|
||||
img.push_back(frame);
|
||||
}
|
||||
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
|
||||
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
|
||||
|
||||
void *buf;
|
||||
final.write_to_buffer(".gif", &buf, DataSize);
|
||||
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
return result;
|
||||
return (char *)buf;
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
Napi::Value Swirl(const Napi::CallbackInfo& info);
|
||||
using std::string;
|
||||
|
||||
char* Swirl(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
108
natives/tile.cc
108
natives/tile.cc
|
@ -1,75 +1,65 @@
|
|||
#include "common.h"
|
||||
#include <Magick++.h>
|
||||
#include <napi.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
|
||||
using namespace std;
|
||||
using namespace Magick;
|
||||
|
||||
Napi::Value Tile(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::Object result = Napi::Object::New(env);
|
||||
char *Tile(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
Blob blob;
|
||||
|
||||
list<Image> frames;
|
||||
list<Image> coalesced;
|
||||
list<Image> mid;
|
||||
try {
|
||||
Napi::Object obj = info[1].As<Napi::Object>();
|
||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||
readImages(&frames, Blob(BufferData, BufferLength));
|
||||
} catch (Magick::WarningCoder &warning) {
|
||||
cerr << "Coder Warning: " << warning.what() << endl;
|
||||
} catch (Magick::Warning &warning) {
|
||||
cerr << "Warning: " << warning.what() << endl;
|
||||
}
|
||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||
|
||||
Blob blob;
|
||||
|
||||
list<Image> frames;
|
||||
list<Image> coalesced;
|
||||
list<Image> mid;
|
||||
try {
|
||||
readImages(&frames, Blob(data.Data(), data.Length()));
|
||||
} catch (Magick::WarningCoder &warning) {
|
||||
cerr << "Coder Warning: " << warning.what() << endl;
|
||||
} catch (Magick::Warning &warning) {
|
||||
cerr << "Warning: " << warning.what() << endl;
|
||||
for (Image &image : coalesced) {
|
||||
list<Image> duplicated;
|
||||
Image appended;
|
||||
list<Image> montage;
|
||||
Image frame;
|
||||
image.magick(*type);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
duplicated.push_back(image);
|
||||
}
|
||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||
|
||||
for (Image &image : coalesced) {
|
||||
list<Image> duplicated;
|
||||
Image appended;
|
||||
list<Image> montage;
|
||||
Image frame;
|
||||
image.magick(type);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
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(image.animationDelay());
|
||||
mid.push_back(frame);
|
||||
appendImages(&appended, duplicated.begin(), duplicated.end());
|
||||
appended.repage();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
montage.push_back(appended);
|
||||
}
|
||||
|
||||
optimizeTransparency(mid.begin(), mid.end());
|
||||
|
||||
if (type == "gif") {
|
||||
for (Image &image : mid) {
|
||||
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
||||
image.quantize();
|
||||
}
|
||||
}
|
||||
|
||||
writeImages(mid.begin(), mid.end(), &blob);
|
||||
|
||||
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
|
||||
blob.length()));
|
||||
result.Set("type", type);
|
||||
} catch (std::exception const &err) {
|
||||
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
|
||||
} catch (...) {
|
||||
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
|
||||
appendImages(&frame, montage.begin(), montage.end(), true);
|
||||
frame.repage();
|
||||
frame.scale(Geometry("800x800>"));
|
||||
frame.animationDelay(image.animationDelay());
|
||||
mid.push_back(frame);
|
||||
}
|
||||
|
||||
return result;
|
||||
optimizeTransparency(mid.begin(), mid.end());
|
||||
|
||||
if (*type == "gif") {
|
||||
for (Image &image : mid) {
|
||||
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
||||
image.quantize();
|
||||
}
|
||||
}
|
||||
|
||||
writeImages(mid.begin(), mid.end(), &blob);
|
||||
|
||||
*DataSize = blob.length();
|
||||
|
||||
char *data = (char *)malloc(*DataSize);
|
||||
memcpy(data, blob.data(), *DataSize);
|
||||
return data;
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
Napi::Value Tile(const Napi::CallbackInfo& info);
|
||||
using std::string;
|
||||
|
||||
char* Tile(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -1,43 +1,32 @@
|
|||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
#include <vips/vips8>
|
||||
|
||||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
Napi::Value ToGif(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::Object result = Napi::Object::New(env);
|
||||
char *ToGif(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
try {
|
||||
Napi::Object obj = info[1].As<Napi::Object>();
|
||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||
if (*type == "gif") {
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
*DataSize = BufferLength;
|
||||
return BufferData;
|
||||
} else {
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
|
||||
if (type == "gif") {
|
||||
result.Set("data", data);
|
||||
result.Set("type", "gif");
|
||||
} else {
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
VImage in = VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
*type == "webp" ? options->set("n", -1)
|
||||
: options);
|
||||
|
||||
VImage in = VImage::new_from_buffer(data.Data(), data.Length(), "",
|
||||
type == "webp" ? options->set("n", -1)
|
||||
: options);
|
||||
void *buf;
|
||||
in.write_to_buffer(".gif", &buf, DataSize);
|
||||
|
||||
void *buf;
|
||||
size_t length;
|
||||
in.write_to_buffer(".gif", &buf, &length);
|
||||
*type = "gif";
|
||||
|
||||
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length));
|
||||
result.Set("type", "gif");
|
||||
}
|
||||
} catch (std::exception const &err) {
|
||||
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
|
||||
} catch (...) {
|
||||
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
return (char *)buf;
|
||||
}
|
||||
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
return result;
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
Napi::Value ToGif(const Napi::CallbackInfo& info);
|
||||
using std::string;
|
||||
|
||||
char* ToGif(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -1,120 +1,104 @@
|
|||
#include "common.h"
|
||||
#include <napi.h>
|
||||
|
||||
#include <vips/vips8>
|
||||
|
||||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
Napi::Value Uncanny(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::Object result = Napi::Object::New(env);
|
||||
char *Uncanny(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
try {
|
||||
Napi::Object obj = info[1].As<Napi::Object>();
|
||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||
string caption = obj.Get("caption").As<Napi::String>().Utf8Value();
|
||||
string caption2 = obj.Get("caption2").As<Napi::String>().Utf8Value();
|
||||
string font = obj.Get("font").As<Napi::String>().Utf8Value();
|
||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||
string path = obj.Get("path").As<Napi::String>().Utf8Value();
|
||||
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||
string caption = GetArgument<string>(Arguments, "caption");
|
||||
string caption2 = GetArgument<string>(Arguments, "caption2");
|
||||
string font = GetArgument<string>(Arguments, "font");
|
||||
string path = GetArgument<string>(Arguments, "path");
|
||||
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(data.Data(), data.Length(), "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB)
|
||||
.extract_band(0, VImage::option()->set("n", 3));
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB)
|
||||
.extract_band(0, VImage::option()->set("n", 3));
|
||||
|
||||
VImage base = VImage::black(1280, 720, VImage::option()->set("bands", 3));
|
||||
VImage base = VImage::black(1280, 720, VImage::option()->set("bands", 3));
|
||||
|
||||
string font_string = (font == "roboto" ? "Roboto Condensed" : font) + ", Twemoji Color Font " +
|
||||
(font != "impact" ? "bold" : "normal") + " 72";
|
||||
string font_string = (font == "roboto" ? "Roboto Condensed" : font) +
|
||||
", Twemoji Color Font " +
|
||||
(font != "impact" ? "bold" : "normal") + " 72";
|
||||
|
||||
string captionText = "<span background=\"black\" foreground=\"white\">" +
|
||||
caption + "</span>";
|
||||
string caption2Text =
|
||||
"<span background=\"black\" foreground=\"red\">" + caption2 + "</span>";
|
||||
string captionText =
|
||||
"<span background=\"black\" foreground=\"white\">" + caption + "</span>";
|
||||
string caption2Text =
|
||||
"<span background=\"black\" foreground=\"red\">" + caption2 + "</span>";
|
||||
|
||||
auto findResult = fontPaths.find(font);
|
||||
if (findResult != fontPaths.end()) {
|
||||
VImage::text(
|
||||
".", VImage::option()->set("fontfile",
|
||||
(basePath + findResult->second).c_str()));
|
||||
}
|
||||
|
||||
VImage text = VImage::text(
|
||||
captionText.c_str(),
|
||||
VImage::option()
|
||||
->set("rgba", true)
|
||||
->set("align", VIPS_ALIGN_CENTRE)
|
||||
->set("font", font_string.c_str())
|
||||
->set("fontfile", (basePath + "assets/fonts/twemoji.otf").c_str())
|
||||
->set("width", 588)
|
||||
->set("height", 90));
|
||||
VImage captionImage =
|
||||
text.extract_band(0, VImage::option()->set("n", 3))
|
||||
.gravity(VIPS_COMPASS_DIRECTION_CENTRE, 640, text.height() + 40,
|
||||
VImage::option()->set("extend", "black"));
|
||||
|
||||
VImage text2 = VImage::text(
|
||||
caption2Text.c_str(),
|
||||
VImage::option()
|
||||
->set("rgba", true)
|
||||
->set("align", VIPS_ALIGN_CENTRE)
|
||||
->set("font", font_string.c_str())
|
||||
->set("fontfile", (basePath + "assets/fonts/twemoji.otf").c_str())
|
||||
->set("width", 588)
|
||||
->set("height", 90));
|
||||
VImage caption2Image =
|
||||
text2.extract_band(0, VImage::option()->set("n", 3))
|
||||
.gravity(VIPS_COMPASS_DIRECTION_CENTRE, 640, text.height() + 40,
|
||||
VImage::option()->set("extend", "black"));
|
||||
|
||||
base = base.insert(captionImage, 0, 0).insert(caption2Image, 640, 0);
|
||||
|
||||
int width = in.width();
|
||||
int pageHeight = vips_image_get_page_height(in.get_image());
|
||||
int nPages = vips_image_get_n_pages(in.get_image());
|
||||
|
||||
VImage uncanny = VImage::new_from_file((basePath + path).c_str());
|
||||
|
||||
base = base.insert(uncanny, 0, 130);
|
||||
|
||||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
VImage resized = img_frame.resize(690.0 / (double)width);
|
||||
if (resized.height() > 590) {
|
||||
double vscale = 590.0 / (double)resized.height();
|
||||
resized =
|
||||
resized.resize(vscale, VImage::option()->set("vscale", vscale));
|
||||
}
|
||||
VImage composited = base.insert(resized, 935 - (resized.width() / 2),
|
||||
425 - (resized.height() / 2));
|
||||
img.push_back(composited);
|
||||
}
|
||||
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
|
||||
final.set(VIPS_META_PAGE_HEIGHT, 720);
|
||||
|
||||
void *buf;
|
||||
size_t length;
|
||||
final.write_to_buffer(("." + type).c_str(), &buf, &length,
|
||||
type == "gif" ? VImage::option()->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length));
|
||||
result.Set("type", type);
|
||||
} catch (std::exception const &err) {
|
||||
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
|
||||
} catch (...) {
|
||||
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
|
||||
auto findResult = fontPaths.find(font);
|
||||
if (findResult != fontPaths.end()) {
|
||||
VImage::text(".", VImage::option()->set(
|
||||
"fontfile", (basePath + findResult->second).c_str()));
|
||||
}
|
||||
|
||||
VImage text = VImage::text(
|
||||
captionText.c_str(),
|
||||
VImage::option()
|
||||
->set("rgba", true)
|
||||
->set("align", VIPS_ALIGN_CENTRE)
|
||||
->set("font", font_string.c_str())
|
||||
->set("fontfile", (basePath + "assets/fonts/twemoji.otf").c_str())
|
||||
->set("width", 588)
|
||||
->set("height", 90));
|
||||
VImage captionImage =
|
||||
text.extract_band(0, VImage::option()->set("n", 3))
|
||||
.gravity(VIPS_COMPASS_DIRECTION_CENTRE, 640, text.height() + 40,
|
||||
VImage::option()->set("extend", "black"));
|
||||
|
||||
VImage text2 = VImage::text(
|
||||
caption2Text.c_str(),
|
||||
VImage::option()
|
||||
->set("rgba", true)
|
||||
->set("align", VIPS_ALIGN_CENTRE)
|
||||
->set("font", font_string.c_str())
|
||||
->set("fontfile", (basePath + "assets/fonts/twemoji.otf").c_str())
|
||||
->set("width", 588)
|
||||
->set("height", 90));
|
||||
VImage caption2Image =
|
||||
text2.extract_band(0, VImage::option()->set("n", 3))
|
||||
.gravity(VIPS_COMPASS_DIRECTION_CENTRE, 640, text.height() + 40,
|
||||
VImage::option()->set("extend", "black"));
|
||||
|
||||
base = base.insert(captionImage, 0, 0).insert(caption2Image, 640, 0);
|
||||
|
||||
int width = in.width();
|
||||
int pageHeight = vips_image_get_page_height(in.get_image());
|
||||
int nPages = vips_image_get_n_pages(in.get_image());
|
||||
|
||||
VImage uncanny = VImage::new_from_file((basePath + path).c_str());
|
||||
|
||||
base = base.insert(uncanny, 0, 130);
|
||||
|
||||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
VImage resized = img_frame.resize(690.0 / (double)width);
|
||||
if (resized.height() > 590) {
|
||||
double vscale = 590.0 / (double)resized.height();
|
||||
resized = resized.resize(vscale, VImage::option()->set("vscale", vscale));
|
||||
}
|
||||
VImage composited = base.insert(resized, 935 - (resized.width() / 2),
|
||||
425 - (resized.height() / 2));
|
||||
img.push_back(composited);
|
||||
}
|
||||
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
|
||||
final.set(VIPS_META_PAGE_HEIGHT, 720);
|
||||
|
||||
void *buf;
|
||||
final.write_to_buffer(("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
return result;
|
||||
return (char *)buf;
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
Napi::Value Uncanny(const Napi::CallbackInfo& info);
|
||||
using std::string;
|
||||
|
||||
char* Uncanny(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -6,7 +6,7 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Uncaption(string type, char *BufferData, size_t BufferLength,
|
||||
char *Uncaption(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
float tolerance = GetArgumentWithFallback<float>(Arguments, "tolerance", 0.5);
|
||||
|
@ -16,7 +16,7 @@ char *Uncaption(string type, char *BufferData, size_t BufferLength,
|
|||
VImage in =
|
||||
VImage::new_from_buffer(
|
||||
BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1)->set("access", "sequential")
|
||||
*type == "gif" ? options->set("n", -1)->set("access", "sequential")
|
||||
: options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
|
@ -47,8 +47,8 @@ char *Uncaption(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
void *buf;
|
||||
final.write_to_buffer(
|
||||
("." + type).c_str(), &buf, DataSize,
|
||||
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
vips_error_clear();
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
using std::map;
|
||||
using std::string;
|
||||
|
||||
char* Uncaption(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Uncaption(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -1,68 +1,58 @@
|
|||
#include "common.h"
|
||||
#include <Magick++.h>
|
||||
#include <napi.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
|
||||
using namespace std;
|
||||
using namespace Magick;
|
||||
|
||||
Napi::Value Wall(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::Object result = Napi::Object::New(env);
|
||||
char *Wall(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
Blob blob;
|
||||
|
||||
list<Image> frames;
|
||||
list<Image> coalesced;
|
||||
list<Image> mid;
|
||||
try {
|
||||
Napi::Object obj = info[1].As<Napi::Object>();
|
||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||
readImages(&frames, Blob(BufferData, BufferLength));
|
||||
} catch (Magick::WarningCoder &warning) {
|
||||
cerr << "Coder Warning: " << warning.what() << endl;
|
||||
} catch (Magick::Warning &warning) {
|
||||
cerr << "Warning: " << warning.what() << endl;
|
||||
}
|
||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||
|
||||
Blob blob;
|
||||
|
||||
list<Image> frames;
|
||||
list<Image> coalesced;
|
||||
list<Image> mid;
|
||||
try {
|
||||
readImages(&frames, Blob(data.Data(), data.Length()));
|
||||
} catch (Magick::WarningCoder &warning) {
|
||||
cerr << "Coder Warning: " << warning.what() << endl;
|
||||
} catch (Magick::Warning &warning) {
|
||||
cerr << "Warning: " << warning.what() << endl;
|
||||
}
|
||||
coalesceImages(&coalesced, frames.begin(), frames.end());
|
||||
|
||||
for (Image &image : coalesced) {
|
||||
image.resize(Geometry("128x128"));
|
||||
image.virtualPixelMethod(Magick::TileVirtualPixelMethod);
|
||||
image.matteColor("none");
|
||||
image.backgroundColor("none");
|
||||
image.scale(Geometry("512x512"));
|
||||
double arguments[16] = {0, 0, 57, 42, 0, 128, 63, 130,
|
||||
128, 0, 140, 60, 128, 128, 140, 140};
|
||||
image.distort(Magick::PerspectiveDistortion, 16, arguments);
|
||||
image.scale(Geometry("800x800>"));
|
||||
image.magick(type);
|
||||
mid.push_back(image);
|
||||
}
|
||||
|
||||
optimizeTransparency(mid.begin(), mid.end());
|
||||
|
||||
if (type == "gif") {
|
||||
for (Image &image : mid) {
|
||||
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
||||
image.quantize();
|
||||
}
|
||||
}
|
||||
|
||||
writeImages(mid.begin(), mid.end(), &blob);
|
||||
|
||||
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)blob.data(),
|
||||
blob.length()));
|
||||
result.Set("type", type);
|
||||
} catch (std::exception const &err) {
|
||||
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
|
||||
} catch (...) {
|
||||
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
|
||||
for (Image &image : coalesced) {
|
||||
image.resize(Geometry("128x128"));
|
||||
image.virtualPixelMethod(Magick::TileVirtualPixelMethod);
|
||||
image.matteColor("none");
|
||||
image.backgroundColor("none");
|
||||
image.scale(Geometry("512x512"));
|
||||
double arguments[16] = {0, 0, 57, 42, 0, 128, 63, 130,
|
||||
128, 0, 140, 60, 128, 128, 140, 140};
|
||||
image.distort(Magick::PerspectiveDistortion, 16, arguments);
|
||||
image.scale(Geometry("800x800>"));
|
||||
image.magick(*type);
|
||||
mid.push_back(image);
|
||||
}
|
||||
|
||||
return result;
|
||||
optimizeTransparency(mid.begin(), mid.end());
|
||||
|
||||
if (*type == "gif") {
|
||||
for (Image &image : mid) {
|
||||
image.quantizeDitherMethod(FloydSteinbergDitherMethod);
|
||||
image.quantize();
|
||||
}
|
||||
}
|
||||
|
||||
writeImages(mid.begin(), mid.end(), &blob);
|
||||
|
||||
*DataSize = blob.length();
|
||||
|
||||
char *data = (char *)malloc(*DataSize);
|
||||
memcpy(data, blob.data(), *DataSize);
|
||||
return data;
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
Napi::Value Wall(const Napi::CallbackInfo& info);
|
||||
using std::string;
|
||||
|
||||
char* Wall(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -6,7 +6,7 @@
|
|||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
char *Watermark(string type, char *BufferData, size_t BufferLength,
|
||||
char *Watermark(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
|
||||
string water = GetArgument<string>(Arguments, "water");
|
||||
|
@ -29,7 +29,7 @@ char *Watermark(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
in = in.bandjoin(255);
|
||||
|
@ -93,7 +93,7 @@ char *Watermark(string type, char *BufferData, size_t BufferLength,
|
|||
VImage frame;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
if (append) {
|
||||
VImage appended = img_frame.join(watermark, VIPS_DIRECTION_VERTICAL,
|
||||
VImage::option()->set("expand", true));
|
||||
|
@ -123,8 +123,8 @@ char *Watermark(string type, char *BufferData, size_t BufferLength,
|
|||
bg = frameAlpha.new_from_image({0, 0, 0}).copy(VImage::option()->set(
|
||||
"interpretation", VIPS_INTERPRETATION_sRGB));
|
||||
frame = bg.bandjoin(frameAlpha);
|
||||
if (type == "jpg" || type == "jpeg") {
|
||||
type = "png";
|
||||
if (*type == "jpg" || *type == "jpeg") {
|
||||
*type = "png";
|
||||
}
|
||||
}
|
||||
VImage content =
|
||||
|
@ -147,8 +147,8 @@ char *Watermark(string type, char *BufferData, size_t BufferLength,
|
|||
|
||||
void *buf;
|
||||
final.write_to_buffer(
|
||||
("." + type).c_str(), &buf, DataSize,
|
||||
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
vips_error_clear();
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
using std::map;
|
||||
using std::string;
|
||||
|
||||
char* Watermark(string type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
||||
char* Watermark(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -1,105 +1,88 @@
|
|||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
#include <vips/vips8>
|
||||
|
||||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
Napi::Value Whisper(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::Object result = Napi::Object::New(env);
|
||||
char *Whisper(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
string caption = GetArgument<string>(Arguments, "caption");
|
||||
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||
|
||||
try {
|
||||
Napi::Object obj = info[1].As<Napi::Object>();
|
||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||
string caption = obj.Get("caption").As<Napi::String>().Utf8Value();
|
||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
in = in.bandjoin(255);
|
||||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(data.Data(), data.Length(), "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
in = in.bandjoin(255);
|
||||
int width = in.width();
|
||||
int pageHeight = vips_image_get_page_height(in.get_image());
|
||||
int nPages = vips_image_get_n_pages(in.get_image());
|
||||
int size = width / 6;
|
||||
int dividedWidth = width / 175;
|
||||
int rad = 1;
|
||||
|
||||
int width = in.width();
|
||||
int pageHeight = vips_image_get_page_height(in.get_image());
|
||||
int nPages = vips_image_get_n_pages(in.get_image());
|
||||
int size = width / 6;
|
||||
int dividedWidth = width / 175;
|
||||
int rad = 1;
|
||||
string font_string = "Upright, Twemoji Color Font " + to_string(size);
|
||||
|
||||
string font_string = "Upright, Twemoji Color Font " + to_string(size);
|
||||
|
||||
VImage mask;
|
||||
if (dividedWidth >= 1) {
|
||||
mask = VImage::black(dividedWidth * 2 + 1, dividedWidth * 2 + 1) + 128;
|
||||
mask.draw_circle({255}, dividedWidth, dividedWidth, dividedWidth,
|
||||
VImage::option()->set("fill", true));
|
||||
} else {
|
||||
mask = VImage::black(rad * 2 + 1, rad * 2 + 1) + 128;
|
||||
mask.draw_circle({255}, rad, rad, rad,
|
||||
VImage::option()->set("fill", true));
|
||||
}
|
||||
|
||||
VImage textIn = VImage::text(
|
||||
".", VImage::option()->set(
|
||||
"fontfile", (basePath + "assets/fonts/whisper.otf").c_str()));
|
||||
textIn = VImage::text(
|
||||
("<span foreground=\"white\">" + caption + "</span>").c_str(),
|
||||
VImage::option()
|
||||
->set("rgba", true)
|
||||
->set("align", VIPS_ALIGN_CENTRE)
|
||||
->set("font", font_string.c_str())
|
||||
->set("fontfile", (basePath + "assets/fonts/twemoji.otf").c_str())
|
||||
->set("width", width));
|
||||
|
||||
textIn = textIn.embed(rad + 10, rad + 10, (textIn.width() + 2 * rad) + 20,
|
||||
(textIn.height() + 2 * rad) + 20);
|
||||
|
||||
VImage outline =
|
||||
textIn.morph(mask, VIPS_OPERATION_MORPHOLOGY_DILATE)
|
||||
.gaussblur(0.5, VImage::option()->set("min_ampl", 0.1));
|
||||
outline = (outline == (vector<double>){0, 0, 0, 0});
|
||||
VImage invert = outline.extract_band(3).invert();
|
||||
outline =
|
||||
outline.extract_band(0, VImage::option()->set("n", outline.bands() - 1))
|
||||
.bandjoin(invert);
|
||||
VImage textImg = outline.composite2(textIn, VIPS_BLEND_MODE_OVER);
|
||||
|
||||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
img_frame = img_frame.composite2(
|
||||
textImg, VIPS_BLEND_MODE_OVER,
|
||||
VImage::option()
|
||||
->set("x", (width / 2) - (textImg.width() / 2))
|
||||
->set("y", (pageHeight / 2) - (textImg.height() / 2)));
|
||||
img.push_back(img_frame);
|
||||
}
|
||||
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
|
||||
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
|
||||
|
||||
void *buf;
|
||||
size_t length;
|
||||
final.write_to_buffer(
|
||||
("." + type).c_str(), &buf, &length,
|
||||
type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length));
|
||||
result.Set("type", type);
|
||||
} catch (std::exception const &err) {
|
||||
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
|
||||
} catch (...) {
|
||||
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
|
||||
VImage mask;
|
||||
if (dividedWidth >= 1) {
|
||||
mask = VImage::black(dividedWidth * 2 + 1, dividedWidth * 2 + 1) + 128;
|
||||
mask.draw_circle({255}, dividedWidth, dividedWidth, dividedWidth,
|
||||
VImage::option()->set("fill", true));
|
||||
} else {
|
||||
mask = VImage::black(rad * 2 + 1, rad * 2 + 1) + 128;
|
||||
mask.draw_circle({255}, rad, rad, rad, VImage::option()->set("fill", true));
|
||||
}
|
||||
|
||||
VImage textIn = VImage::text(
|
||||
".", VImage::option()->set(
|
||||
"fontfile", (basePath + "assets/fonts/whisper.otf").c_str()));
|
||||
textIn = VImage::text(
|
||||
("<span foreground=\"white\">" + caption + "</span>").c_str(),
|
||||
VImage::option()
|
||||
->set("rgba", true)
|
||||
->set("align", VIPS_ALIGN_CENTRE)
|
||||
->set("font", font_string.c_str())
|
||||
->set("fontfile", (basePath + "assets/fonts/twemoji.otf").c_str())
|
||||
->set("width", width));
|
||||
|
||||
textIn = textIn.embed(rad + 10, rad + 10, (textIn.width() + 2 * rad) + 20,
|
||||
(textIn.height() + 2 * rad) + 20);
|
||||
|
||||
VImage outline = textIn.morph(mask, VIPS_OPERATION_MORPHOLOGY_DILATE)
|
||||
.gaussblur(0.5, VImage::option()->set("min_ampl", 0.1));
|
||||
outline = (outline == (vector<double>){0, 0, 0, 0});
|
||||
VImage invert = outline.extract_band(3).invert();
|
||||
outline =
|
||||
outline.extract_band(0, VImage::option()->set("n", outline.bands() - 1))
|
||||
.bandjoin(invert);
|
||||
VImage textImg = outline.composite2(textIn, VIPS_BLEND_MODE_OVER);
|
||||
|
||||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
img_frame = img_frame.composite2(
|
||||
textImg, VIPS_BLEND_MODE_OVER,
|
||||
VImage::option()
|
||||
->set("x", (width / 2) - (textImg.width() / 2))
|
||||
->set("y", (pageHeight / 2) - (textImg.height() / 2)));
|
||||
img.push_back(img_frame);
|
||||
}
|
||||
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
|
||||
final.set(VIPS_META_PAGE_HEIGHT, pageHeight);
|
||||
|
||||
void *buf;
|
||||
final.write_to_buffer(
|
||||
("." + *type).c_str(), &buf, DataSize,
|
||||
*type == "gif" ? VImage::option()->set("dither", 0)->set("reoptimise", 1)
|
||||
: 0);
|
||||
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
return result;
|
||||
return (char *)buf;
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
Napi::Value Whisper(const Napi::CallbackInfo& info);
|
||||
using std::string;
|
||||
|
||||
char* Whisper(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -1,62 +1,50 @@
|
|||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
#include <vips/vips8>
|
||||
|
||||
using namespace std;
|
||||
using namespace vips;
|
||||
|
||||
Napi::Value Zamn(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
Napi::Object result = Napi::Object::New(env);
|
||||
char *Zamn(string *type, char *BufferData, size_t BufferLength,
|
||||
ArgumentMap Arguments, size_t *DataSize) {
|
||||
string basePath = GetArgument<string>(Arguments, "basePath");
|
||||
|
||||
try {
|
||||
Napi::Object obj = info[1].As<Napi::Object>();
|
||||
Napi::Buffer<char> data = obj.Get("data").As<Napi::Buffer<char>>();
|
||||
string type = obj.Get("type").As<Napi::String>().Utf8Value();
|
||||
string basePath = obj.Get("basePath").As<Napi::String>().Utf8Value();
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
|
||||
VOption *options = VImage::option()->set("access", "sequential");
|
||||
VImage in =
|
||||
VImage::new_from_buffer(BufferData, BufferLength, "",
|
||||
*type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha())
|
||||
in = in.bandjoin(255);
|
||||
|
||||
VImage in =
|
||||
VImage::new_from_buffer(data.Data(), data.Length(), "",
|
||||
type == "gif" ? options->set("n", -1) : options)
|
||||
.colourspace(VIPS_INTERPRETATION_sRGB);
|
||||
if (!in.has_alpha()) in = in.bandjoin(255);
|
||||
int width = in.width();
|
||||
int pageHeight = vips_image_get_page_height(in.get_image());
|
||||
int nPages = vips_image_get_n_pages(in.get_image());
|
||||
|
||||
int width = in.width();
|
||||
int pageHeight = vips_image_get_page_height(in.get_image());
|
||||
int nPages = vips_image_get_n_pages(in.get_image());
|
||||
string assetPath = basePath + "assets/images/zamn.png";
|
||||
VImage tmpl = VImage::new_from_file(assetPath.c_str());
|
||||
|
||||
string assetPath = basePath + "assets/images/zamn.png";
|
||||
VImage tmpl = VImage::new_from_file(assetPath.c_str());
|
||||
|
||||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
VImage composited = tmpl.insert(
|
||||
img_frame.extract_band(0, VImage::option()->set("n", 3)).bandjoin(255).resize(
|
||||
303.0 / (double)width,
|
||||
VImage::option()->set("vscale", 438.0 / (double)pageHeight)),
|
||||
310, 76);
|
||||
img.push_back(composited);
|
||||
}
|
||||
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
|
||||
final.set(VIPS_META_PAGE_HEIGHT, 516);
|
||||
|
||||
void *buf;
|
||||
size_t length;
|
||||
final.write_to_buffer(("." + type).c_str(), &buf, &length);
|
||||
|
||||
result.Set("data", Napi::Buffer<char>::Copy(env, (char *)buf, length));
|
||||
result.Set("type", type);
|
||||
} catch (std::exception const &err) {
|
||||
Napi::Error::New(env, err.what()).ThrowAsJavaScriptException();
|
||||
} catch (...) {
|
||||
Napi::Error::New(env, "Unknown error").ThrowAsJavaScriptException();
|
||||
vector<VImage> img;
|
||||
for (int i = 0; i < nPages; i++) {
|
||||
VImage img_frame =
|
||||
*type == "gif" ? in.crop(0, i * pageHeight, width, pageHeight) : in;
|
||||
VImage composited =
|
||||
tmpl.insert(img_frame.extract_band(0, VImage::option()->set("n", 3))
|
||||
.bandjoin(255)
|
||||
.resize(303.0 / (double)width,
|
||||
VImage::option()->set(
|
||||
"vscale", 438.0 / (double)pageHeight)),
|
||||
310, 76);
|
||||
img.push_back(composited);
|
||||
}
|
||||
VImage final = VImage::arrayjoin(img, VImage::option()->set("across", 1));
|
||||
final.set(VIPS_META_PAGE_HEIGHT, 516);
|
||||
|
||||
void *buf;
|
||||
final.write_to_buffer(("." + *type).c_str(), &buf, DataSize);
|
||||
|
||||
vips_error_clear();
|
||||
vips_thread_shutdown();
|
||||
return result;
|
||||
return (char *)buf;
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <napi.h>
|
||||
#include "common.h"
|
||||
|
||||
Napi::Value Zamn(const Napi::CallbackInfo& info);
|
||||
using std::string;
|
||||
|
||||
char* Zamn(string* type, char* BufferData, size_t BufferLength, ArgumentMap Arguments, size_t* DataSize);
|
|
@ -6,7 +6,7 @@ let dirSizeCache;
|
|||
export async function upload(client, result, context, interaction = false) {
|
||||
const filename = `${Math.random().toString(36).substring(2, 15)}.${result.name.split(".")[1]}`;
|
||||
await writeFile(`${process.env.TEMPDIR}/${filename}`, result.contents);
|
||||
const imageURL = `${process.env.TMP_DOMAIN || "https://tmp.projectlounge.pw"}/${filename}`;
|
||||
const imageURL = `${process.env.TMP_DOMAIN || "https://tmp.esmbot.net"}/${filename}`;
|
||||
const payload = {
|
||||
embeds: [{
|
||||
color: 16711680,
|
||||
|
|
Loading…
Reference in a new issue