mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Use bounding box of alpha+non-alpha for trim op #2166
This commit is contained in:
parent
e3cab7f10f
commit
e0d3c6e05d
@ -236,7 +236,8 @@ Returns **Sharp**
|
||||
## trim
|
||||
|
||||
Trim "boring" pixels from all edges that contain values similar to the top-left pixel.
|
||||
Images consisting entirely of a single colour will calculate "boring" using the alpha channel, if any.
|
||||
|
||||
Images with an alpha channel will use the combined bounding box of alpha and non-alpha channels.
|
||||
|
||||
The `info` response Object, obtained from callback of `.toFile()` or `.toBuffer()`,
|
||||
will contain `trimOffsetLeft` and `trimOffsetTop` properties.
|
||||
|
@ -8,6 +8,9 @@ Requires libvips v8.13.0
|
||||
|
||||
* Drop support for Node.js 12, now requires Node.js >= 14.15.0.
|
||||
|
||||
* Use combined bounding box of alpha and non-alpha channels for `trim` operation.
|
||||
[#2166](https://github.com/lovell/sharp/issues/2166)
|
||||
|
||||
* Re-introduce support for greyscale ICC profiles (temporarily removed in 0.30.2).
|
||||
[#3114](https://github.com/lovell/sharp/issues/3114)
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -430,7 +430,8 @@ function extract (options) {
|
||||
|
||||
/**
|
||||
* Trim "boring" pixels from all edges that contain values similar to the top-left pixel.
|
||||
* Images consisting entirely of a single colour will calculate "boring" using the alpha channel, if any.
|
||||
*
|
||||
* Images with an alpha channel will use the combined bounding box of alpha and non-alpha channels.
|
||||
*
|
||||
* The `info` response Object, obtained from callback of `.toFile()` or `.toBuffer()`,
|
||||
* will contain `trimOffsetLeft` and `trimOffsetTop` properties.
|
||||
|
@ -275,19 +275,31 @@ namespace sharp {
|
||||
left = image.find_trim(&top, &width, &height, VImage::option()
|
||||
->set("background", background(0, 0))
|
||||
->set("threshold", threshold));
|
||||
if (width == 0 || height == 0) {
|
||||
if (HasAlpha(image)) {
|
||||
// Search alpha channel
|
||||
// Search alpha channel (A)
|
||||
int leftA, topA, widthA, heightA;
|
||||
VImage alpha = image[image.bands() - 1];
|
||||
VImage backgroundAlpha = alpha.extract_area(0, 0, 1, 1);
|
||||
left = alpha.find_trim(&top, &width, &height, VImage::option()
|
||||
leftA = alpha.find_trim(&topA, &widthA, &heightA, VImage::option()
|
||||
->set("background", backgroundAlpha(0, 0))
|
||||
->set("threshold", threshold));
|
||||
if (widthA > 0 && heightA > 0) {
|
||||
if (width > 0 && height > 0) {
|
||||
// Combined bounding box (B)
|
||||
int const leftB = std::min(left, leftA);
|
||||
int const topB = std::min(top, topA);
|
||||
int const widthB = std::max(left + width, leftA + widthA) - leftB;
|
||||
int const heightB = std::max(top + height, topA + heightA) - topB;
|
||||
return image.extract_area(leftB, topB, widthB, heightB);
|
||||
} else {
|
||||
// Use alpha only
|
||||
return image.extract_area(leftA, topA, widthA, heightA);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (width == 0 || height == 0) {
|
||||
throw VError("Unexpected error while trimming. Try to lower the tolerance");
|
||||
}
|
||||
}
|
||||
return image.extract_area(left, top, width, height);
|
||||
}
|
||||
|
||||
|
1
test/fixtures/index.js
vendored
1
test/fixtures/index.js
vendored
@ -94,6 +94,7 @@ module.exports = {
|
||||
inputPngSolidAlpha: getPath('with-alpha.png'), // https://github.com/lovell/sharp/issues/1599
|
||||
inputPngP3: getPath('p3.png'), // https://github.com/lovell/sharp/issues/2862
|
||||
inputPngPalette: getPath('swiss.png'), // https://github.com/randy408/libspng/issues/188
|
||||
inputPngTrimIncludeAlpha: getPath('trim-mc.png'), // https://github.com/lovell/sharp/issues/2166
|
||||
|
||||
inputWebP: getPath('4.webp'), // http://www.gstatic.com/webp/gallery/4.webp
|
||||
inputWebPWithTransparency: getPath('5_webp_a.webp'), // http://www.gstatic.com/webp/gallery3/5_webp_a.webp
|
||||
|
BIN
test/fixtures/trim-mc.png
vendored
Normal file
BIN
test/fixtures/trim-mc.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
@ -128,6 +128,18 @@ describe('Trim borders', function () {
|
||||
)
|
||||
);
|
||||
|
||||
it('Ensure trim uses bounding box of alpha and non-alpha channels', async () => {
|
||||
const { info } = await sharp(fixtures.inputPngTrimIncludeAlpha)
|
||||
.trim()
|
||||
.toBuffer({ resolveWithObject: true });
|
||||
|
||||
const { width, height, trimOffsetTop, trimOffsetLeft } = info;
|
||||
assert.strictEqual(width, 179);
|
||||
assert.strictEqual(height, 123);
|
||||
assert.strictEqual(trimOffsetTop, -44);
|
||||
assert.strictEqual(trimOffsetLeft, -13);
|
||||
});
|
||||
|
||||
describe('Invalid thresholds', function () {
|
||||
[-1, 'fail', {}].forEach(function (threshold) {
|
||||
it(JSON.stringify(threshold), function () {
|
||||
|
Loading…
x
Reference in New Issue
Block a user