Ensure withoutReduction does not interfere with contain/crop/embed (#3081)

This commit is contained in:
Kleis Auke Wolthuizen 2022-02-08 22:22:23 +01:00 committed by GitHub
parent 7eb5efa3a3
commit 83db5f8a2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 14 additions and 54 deletions

View File

@ -885,7 +885,7 @@ namespace sharp {
} }
std::pair<double, double> ResolveShrink(int width, int height, int targetWidth, int targetHeight, std::pair<double, double> ResolveShrink(int width, int height, int targetWidth, int targetHeight,
Canvas canvas, bool swap, bool withoutEnlargement) { Canvas canvas, bool swap, bool withoutEnlargement, bool withoutReduction) {
if (swap) { if (swap) {
// Swap input width and height when requested. // Swap input width and height when requested.
std::swap(width, height); std::swap(width, height);
@ -940,9 +940,14 @@ namespace sharp {
} }
} }
// We should not enlarge (oversample) the output image, // We should not reduce or enlarge the output image, if
// if withoutEnlargement is specified. // withoutReduction or withoutEnlargement is specified.
if (withoutEnlargement) { if (withoutReduction) {
// Equivalent of VIPS_SIZE_UP
hshrink = std::min(1.0, hshrink);
vshrink = std::min(1.0, vshrink);
} else if (withoutEnlargement) {
// Equivalent of VIPS_SIZE_DOWN
hshrink = std::max(1.0, hshrink); hshrink = std::max(1.0, hshrink);
vshrink = std::max(1.0, vshrink); vshrink = std::max(1.0, vshrink);
} }

View File

@ -345,7 +345,7 @@ namespace sharp {
the required thumbnail width/height and canvas mode. the required thumbnail width/height and canvas mode.
*/ */
std::pair<double, double> ResolveShrink(int width, int height, int targetWidth, int targetHeight, std::pair<double, double> ResolveShrink(int width, int height, int targetWidth, int targetHeight,
Canvas canvas, bool swap, bool withoutEnlargement); Canvas canvas, bool swap, bool withoutEnlargement, bool withoutReduction);
} // namespace sharp } // namespace sharp

View File

@ -138,17 +138,6 @@ class PipelineWorker : public Napi::AsyncWorker {
pageHeight = inputHeight; pageHeight = inputHeight;
} }
// If withoutReduction is specified,
// Override target width and height if less than respective value from input file
if (baton->withoutReduction) {
if (baton->width < inputWidth) {
baton->width = inputWidth;
}
if (baton->height < inputHeight) {
baton->height = inputHeight;
}
}
// Scaling calculations // Scaling calculations
double hshrink; double hshrink;
double vshrink; double vshrink;
@ -161,7 +150,7 @@ class PipelineWorker : public Napi::AsyncWorker {
// Shrink to pageHeight, so we work for multi-page images // Shrink to pageHeight, so we work for multi-page images
std::tie(hshrink, vshrink) = sharp::ResolveShrink( std::tie(hshrink, vshrink) = sharp::ResolveShrink(
inputWidth, pageHeight, targetResizeWidth, targetResizeHeight, inputWidth, pageHeight, targetResizeWidth, targetResizeHeight,
baton->canvas, swap, baton->withoutEnlargement); baton->canvas, swap, baton->withoutEnlargement, baton->withoutReduction);
// The jpeg preload shrink. // The jpeg preload shrink.
int jpegShrinkOnLoad = 1; int jpegShrinkOnLoad = 1;
@ -286,7 +275,7 @@ class PipelineWorker : public Napi::AsyncWorker {
// Shrink to pageHeight, so we work for multi-page images // Shrink to pageHeight, so we work for multi-page images
std::tie(hshrink, vshrink) = sharp::ResolveShrink( std::tie(hshrink, vshrink) = sharp::ResolveShrink(
inputWidth, pageHeight, targetResizeWidth, targetResizeHeight, inputWidth, pageHeight, targetResizeWidth, targetResizeHeight,
baton->canvas, swap, baton->withoutEnlargement); baton->canvas, swap, baton->withoutEnlargement, baton->withoutReduction);
int targetHeight = static_cast<int>(std::rint(static_cast<double>(pageHeight) / vshrink)); int targetHeight = static_cast<int>(std::rint(static_cast<double>(pageHeight) / vshrink));
int targetPageHeight = targetHeight; int targetPageHeight = targetHeight;

View File

@ -368,7 +368,7 @@ describe('Resize dimensions', function () {
assert.strictEqual(true, data.length > 0); assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format); assert.strictEqual('jpeg', info.format);
assert.strictEqual(2800, info.width); assert.strictEqual(2800, info.width);
assert.strictEqual(2225, info.height); assert.strictEqual(2286, info.height);
done(); done();
}); });
}); });
@ -383,46 +383,12 @@ describe('Resize dimensions', function () {
if (err) throw err; if (err) throw err;
assert.strictEqual(true, data.length > 0); assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format); assert.strictEqual('jpeg', info.format);
assert.strictEqual(2725, info.width); assert.strictEqual(2817, info.width);
assert.strictEqual(2300, info.height); assert.strictEqual(2300, info.height);
done(); done();
}); });
}); });
it('Do not crop when fit = cover and withoutReduction = true and width >= outputWidth, and height < outputHeight', function (done) {
sharp(fixtures.inputJpg)
.resize({
width: 3000,
height: 1000,
withoutReduction: true
})
.toBuffer(function (err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(3000, info.width);
assert.strictEqual(2225, info.height);
done();
});
});
it('Do not crop when fit = cover and withoutReduction = true and width < outputWidth, and height >= outputHeight', function (done) {
sharp(fixtures.inputJpg)
.resize({
width: 1500,
height: 2226,
withoutReduction: true
})
.toBuffer(function (err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(2725, info.width);
assert.strictEqual(2226, info.height);
done();
});
});
it('Do enlarge when input width is less than output width', function (done) { it('Do enlarge when input width is less than output width', function (done) {
sharp(fixtures.inputJpg) sharp(fixtures.inputJpg)
.resize({ .resize({