Add trim option to provide a specific background colour (#3332)

Co-authored-by: Mart Jansink <mart@cinemait.nl>
This commit is contained in:
Mart
2022-08-23 13:28:02 +02:00
committed by GitHub
parent 3a44748f49
commit c3a852eecf
14 changed files with 240 additions and 45 deletions

View File

@@ -262,26 +262,42 @@ namespace sharp {
/*
Trim an image
*/
VImage Trim(VImage image, double const threshold) {
VImage Trim(VImage image, std::vector<double> background, double threshold) {
if (image.width() < 3 && image.height() < 3) {
throw VError("Image to trim must be at least 3x3 pixels");
}
// Top-left pixel provides the background colour
VImage background = image.extract_area(0, 0, 1, 1);
if (HasAlpha(background)) {
background = background.flatten();
// Scale up 8-bit values to match 16-bit input image
double multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0;
threshold *= multiplier;
std::vector<double> backgroundAlpha(1);
if (background.size() == 0) {
// Top-left pixel provides the default background colour if none is given
background = image.extract_area(0, 0, 1, 1)(0, 0);
multiplier = 1.0;
}
if (background.size() == 4) {
// Just discard the alpha because flattening the background colour with
// itself (effectively what find_trim() does) gives the same result
backgroundAlpha[0] = background[3] * multiplier;
}
background = {
background[0] * multiplier,
background[1] * multiplier,
background[2] * multiplier
};
int left, top, width, height;
left = image.find_trim(&top, &width, &height, VImage::option()
->set("background", background(0, 0))
->set("background", background)
->set("threshold", threshold));
if (HasAlpha(image)) {
// Search alpha channel (A)
int leftA, topA, widthA, heightA;
VImage alpha = image[image.bands() - 1];
VImage backgroundAlpha = alpha.extract_area(0, 0, 1, 1);
leftA = alpha.find_trim(&topA, &widthA, &heightA, VImage::option()
->set("background", backgroundAlpha(0, 0))
->set("background", backgroundAlpha)
->set("threshold", threshold));
if (widthA > 0 && heightA > 0) {
if (width > 0 && height > 0) {

View File

@@ -85,7 +85,7 @@ namespace sharp {
/*
Trim an image
*/
VImage Trim(VImage image, double const threshold);
VImage Trim(VImage image, std::vector<double> background, double const threshold);
/*
* Linear adjustment (a * in + b)

View File

@@ -118,7 +118,7 @@ class PipelineWorker : public Napi::AsyncWorker {
// Trim
if (baton->trimThreshold > 0.0) {
MultiPageUnsupported(nPages, "Trim");
image = sharp::Trim(image, baton->trimThreshold);
image = sharp::Trim(image, baton->trimBackground, baton->trimThreshold);
baton->trimOffsetLeft = image.xoffset();
baton->trimOffsetTop = image.yoffset();
}
@@ -1451,6 +1451,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
baton->sharpenY3 = sharp::AttrAsDouble(options, "sharpenY3");
baton->threshold = sharp::AttrAsInt32(options, "threshold");
baton->thresholdGrayscale = sharp::AttrAsBool(options, "thresholdGrayscale");
baton->trimBackground = sharp::AttrAsVectorOfDouble(options, "trimBackground");
baton->trimThreshold = sharp::AttrAsDouble(options, "trimThreshold");
baton->gamma = sharp::AttrAsDouble(options, "gamma");
baton->gammaOut = sharp::AttrAsDouble(options, "gammaOut");

View File

@@ -97,6 +97,7 @@ struct PipelineBaton {
double sharpenY3;
int threshold;
bool thresholdGrayscale;
std::vector<double> trimBackground;
double trimThreshold;
int trimOffsetLeft;
int trimOffsetTop;
@@ -248,6 +249,7 @@ struct PipelineBaton {
sharpenY3(20.0),
threshold(0),
thresholdGrayscale(true),
trimBackground{},
trimThreshold(0.0),
trimOffsetLeft(0),
trimOffsetTop(0),