Add gravity support to embed feature (#1038)

This commit is contained in:
Kenric D'Souza
2017-12-13 00:59:16 +05:30
committed by Lovell Fuller
parent 1d7a0ea99e
commit 927b77700d
28 changed files with 426 additions and 7 deletions

View File

@@ -409,7 +409,62 @@ namespace sharp {
/*
Calculate the (left, top) coordinates of the output image
within the input image, applying the given gravity.
within the input image, applying the given gravity during an embed.
@Azurebyte: We are basically swapping the inWidth and outWidth, inHeight and outHeight from the CalculateCrop function.
*/
std::tuple<int, int> CalculateEmbedPosition(int const inWidth, int const inHeight,
int const outWidth, int const outHeight, int const gravity) {
int left = 0;
int top = 0;
switch (gravity) {
case 1:
// North
left = (outWidth - inWidth) / 2;
break;
case 2:
// East
left = outWidth - inWidth;
top = (outHeight - inHeight) / 2;
break;
case 3:
// South
left = (outWidth - inWidth) / 2;
top = outHeight - inHeight;
break;
case 4:
// West
top = (outHeight - inHeight) / 2;
break;
case 5:
// Northeast
left = outWidth - inWidth;
break;
case 6:
// Southeast
left = outWidth - inWidth;
top = outHeight - inHeight;
break;
case 7:
// Southwest
top = outHeight - inHeight;
break;
case 8:
// Northwest
// Which is the default is 0,0 so we do not assign anything here.
break;
default:
// Centre
left = (outWidth - inWidth) / 2;
top = (outHeight - inHeight) / 2;
}
return std::make_tuple(left, top);
}
/*
Calculate the (left, top) coordinates of the output image
within the input image, applying the given gravity during a crop.
*/
std::tuple<int, int> CalculateCrop(int const inWidth, int const inHeight,
int const outWidth, int const outHeight, int const gravity) {

View File

@@ -206,6 +206,13 @@ namespace sharp {
*/
std::string VipsWarningPop();
/*
Calculate the (left, top) coordinates of the output image
within the input image, applying the given gravity during an embed.
*/
std::tuple<int, int> CalculateEmbedPosition(int const inWidth, int const inHeight,
int const outWidth, int const outHeight, int const gravity);
/*
Calculate the (left, top) coordinates of the output image
within the input image, applying the given gravity.

View File

@@ -446,12 +446,25 @@ class PipelineWorker : public Nan::AsyncWorker {
image = image.bandjoin(
VImage::new_matrix(image.width(), image.height()).new_from_image(255 * multiplier));
}
// Embed
int left = static_cast<int>(round((baton->width - image.width()) / 2));
int top = static_cast<int>(round((baton->height - image.height()) / 2));
image = image.embed(left, top, baton->width, baton->height, VImage::option()
// Calculate where to position the embeded image if gravity specified, else center.
int left;
int top;
left = static_cast<int>(round((baton->width - image.width()) / 2));
top = static_cast<int>(round((baton->height - image.height()) / 2));
int width = std::max(image.width(), baton->width);
int height = std::max(image.height(), baton->height);
std::tie(left, top) = sharp::CalculateEmbedPosition(
image.width(), image.height(), baton->width, baton->height, baton->embed);
image = image.embed(left, top, width, height, VImage::option()
->set("extend", VIPS_EXTEND_BACKGROUND)
->set("background", background));
} else if (baton->canvas != Canvas::IGNORE_ASPECT) {
// Crop/max/min
if (baton->crop < 9) {
@@ -1141,6 +1154,7 @@ NAN_METHOD(pipeline) {
// Resize options
baton->withoutEnlargement = AttrTo<bool>(options, "withoutEnlargement");
baton->crop = AttrTo<int32_t>(options, "crop");
baton->embed = AttrTo<int32_t>(options, "embed");
baton->kernel = AttrAsStr(options, "kernel");
baton->fastShrinkOnLoad = AttrTo<bool>(options, "fastShrinkOnLoad");
// Join Channel Options

View File

@@ -62,6 +62,7 @@ struct PipelineBaton {
int channels;
Canvas canvas;
int crop;
int embed;
bool hasCropOffset;
int cropOffsetLeft;
int cropOffsetTop;
@@ -145,6 +146,7 @@ struct PipelineBaton {
channels(0),
canvas(Canvas::CROP),
crop(0),
embed(0),
hasCropOffset(false),
cropOffsetLeft(0),
cropOffsetTop(0),