mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 18:40:16 +02:00
Ensure conv kernel scale is clamped to min val of 1 #561
This commit is contained in:
parent
7c06a48ec0
commit
af9d09f8ae
@ -4,6 +4,12 @@
|
|||||||
|
|
||||||
Requires libvips v8.3.3
|
Requires libvips v8.3.3
|
||||||
|
|
||||||
|
#### v0.16.1 - TBD
|
||||||
|
|
||||||
|
* Ensure convolution kernel scale is clamped to a minimum value of 1.
|
||||||
|
[#561](https://github.com/lovell/sharp/issues/561)
|
||||||
|
[@abagshaw](https://github.com/abagshaw)
|
||||||
|
|
||||||
#### v0.16.0 - 18<sup>th</sup> August 2016
|
#### v0.16.0 - 18<sup>th</sup> August 2016
|
||||||
|
|
||||||
* Add pre-compiled libvips for OS X, ARMv7 and ARMv8.
|
* Add pre-compiled libvips for OS X, ARMv7 and ARMv8.
|
||||||
|
21
index.js
21
index.js
@ -503,22 +503,25 @@ Sharp.prototype.blur = function(sigma) {
|
|||||||
Convolve the image with a kernel.
|
Convolve the image with a kernel.
|
||||||
*/
|
*/
|
||||||
Sharp.prototype.convolve = function(kernel) {
|
Sharp.prototype.convolve = function(kernel) {
|
||||||
if (!isDefined(kernel) || !isDefined(kernel.kernel) ||
|
if (!isObject(kernel) || !Array.isArray(kernel.kernel) ||
|
||||||
!isDefined(kernel.width) || !isDefined(kernel.height) ||
|
!isInteger(kernel.width) || !isInteger(kernel.height) ||
|
||||||
!inRange(kernel.width, 3, 1001) || !inRange(kernel.height, 3, 1001) ||
|
!inRange(kernel.width, 3, 1001) || !inRange(kernel.height, 3, 1001) ||
|
||||||
kernel.height * kernel.width != kernel.kernel.length
|
kernel.height * kernel.width != kernel.kernel.length
|
||||||
) {
|
) {
|
||||||
// must pass in a kernel
|
// must pass in a kernel
|
||||||
throw new Error('Invalid convolution kernel');
|
throw new Error('Invalid convolution kernel');
|
||||||
}
|
}
|
||||||
if(!isDefined(kernel.scale)) {
|
// Default scale is sum of kernel values
|
||||||
var sum = 0;
|
if (!isInteger(kernel.scale)) {
|
||||||
kernel.kernel.forEach(function(e) {
|
kernel.scale = kernel.kernel.reduce(function(a, b) {
|
||||||
sum += e;
|
return a + b;
|
||||||
});
|
}, 0);
|
||||||
kernel.scale = sum;
|
|
||||||
}
|
}
|
||||||
if(!isDefined(kernel.offset)) {
|
// Clamp scale to a minimum value of 1
|
||||||
|
if (kernel.scale < 1) {
|
||||||
|
kernel.scale = 1;
|
||||||
|
}
|
||||||
|
if (!isInteger(kernel.offset)) {
|
||||||
kernel.offset = 0;
|
kernel.offset = 0;
|
||||||
}
|
}
|
||||||
this.options.convKernel = kernel;
|
this.options.convKernel = kernel;
|
||||||
|
BIN
test/fixtures/expected/conv-sobel-horizontal.jpg
vendored
Normal file
BIN
test/fixtures/expected/conv-sobel-horizontal.jpg
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
@ -9,18 +9,17 @@ describe('Convolve', function() {
|
|||||||
|
|
||||||
it('specific convolution kernel 1', function(done) {
|
it('specific convolution kernel 1', function(done) {
|
||||||
sharp(fixtures.inputPngStripesV)
|
sharp(fixtures.inputPngStripesV)
|
||||||
.resize(320, 240)
|
.convolve({
|
||||||
.convolve(
|
width: 3,
|
||||||
{
|
height: 3,
|
||||||
'width': 3,
|
scale: 50,
|
||||||
'height': 3,
|
offset: 0,
|
||||||
'scale': 50,
|
kernel: [ 10, 20, 10,
|
||||||
'offset': 0,
|
|
||||||
'kernel': [ 10, 20, 10,
|
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
10, 20, 10 ]
|
10, 20, 10 ]
|
||||||
})
|
})
|
||||||
.toBuffer(function(err, data, info) {
|
.toBuffer(function(err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
assert.strictEqual('png', info.format);
|
assert.strictEqual('png', info.format);
|
||||||
assert.strictEqual(320, info.width);
|
assert.strictEqual(320, info.width);
|
||||||
assert.strictEqual(240, info.height);
|
assert.strictEqual(240, info.height);
|
||||||
@ -30,16 +29,15 @@ describe('Convolve', function() {
|
|||||||
|
|
||||||
it('specific convolution kernel 2', function(done) {
|
it('specific convolution kernel 2', function(done) {
|
||||||
sharp(fixtures.inputPngStripesH)
|
sharp(fixtures.inputPngStripesH)
|
||||||
.resize(320, 240)
|
.convolve({
|
||||||
.convolve(
|
width: 3,
|
||||||
{
|
height: 3,
|
||||||
'width': 3,
|
kernel: [ 1, 0, 1,
|
||||||
'height': 3,
|
|
||||||
'kernel': [ 1, 0, 1,
|
|
||||||
2, 0, 2,
|
2, 0, 2,
|
||||||
1, 0, 1 ]
|
1, 0, 1 ]
|
||||||
})
|
})
|
||||||
.toBuffer(function(err, data, info) {
|
.toBuffer(function(err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
assert.strictEqual('png', info.format);
|
assert.strictEqual('png', info.format);
|
||||||
assert.strictEqual(320, info.width);
|
assert.strictEqual(320, info.width);
|
||||||
assert.strictEqual(240, info.height);
|
assert.strictEqual(240, info.height);
|
||||||
@ -47,35 +45,47 @@ describe('Convolve', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('invalid kernel specification: no data', function() {
|
it('horizontal Sobel operator', function(done) {
|
||||||
assert.throws(function() {
|
sharp(fixtures.inputJpg)
|
||||||
sharp(fixtures.inputJpg).convolve(
|
.resize(320, 240)
|
||||||
{
|
.convolve({
|
||||||
'width': 3,
|
width: 3,
|
||||||
'height': 3,
|
height: 3,
|
||||||
'kernel': []
|
kernel: [ -1, 0, 1,
|
||||||
});
|
-2, 0, 2,
|
||||||
|
-1, 0, 1 ]
|
||||||
|
})
|
||||||
|
.toBuffer(function(err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual('jpeg', info.format);
|
||||||
|
assert.strictEqual(320, info.width);
|
||||||
|
assert.strictEqual(240, info.height);
|
||||||
|
fixtures.assertSimilar(fixtures.expected('conv-sobel-horizontal.jpg'), data, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('invalid kernel specification: bad data format', function() {
|
describe('invalid kernel specification', function() {
|
||||||
|
it('missing', function() {
|
||||||
assert.throws(function() {
|
assert.throws(function() {
|
||||||
sharp(fixtures.inputJpg).convolve(
|
sharp(fixtures.inputJpg).convolve({});
|
||||||
{
|
|
||||||
'width': 3,
|
|
||||||
'height': 3,
|
|
||||||
'kernel': [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
it('incorrect data format', function() {
|
||||||
|
|
||||||
it('invalid kernel specification: wrong width', function() {
|
|
||||||
assert.throws(function() {
|
assert.throws(function() {
|
||||||
sharp(fixtures.inputJpg).convolve(
|
sharp(fixtures.inputJpg).convolve({
|
||||||
{
|
width: 3,
|
||||||
'width': 3,
|
height: 3,
|
||||||
'height': 4,
|
kernel: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
|
||||||
'kernel': [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('incorrect dimensions', function() {
|
||||||
|
assert.throws(function() {
|
||||||
|
sharp(fixtures.inputJpg).convolve({
|
||||||
|
width: 3,
|
||||||
|
height: 4,
|
||||||
|
kernel: [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user