mirror of
https://github.com/lovell/sharp.git
synced 2025-12-19 07:15:08 +01:00
Add gravity support to embed feature (#1038)
This commit is contained in:
committed by
Lovell Fuller
parent
1d7a0ea99e
commit
927b77700d
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user