diff --git a/docs/api.md b/docs/api.md index 52731882..03d1d3a5 100644 --- a/docs/api.md +++ b/docs/api.md @@ -383,18 +383,27 @@ When a `sigma` is provided, performs a slower, more accurate Gaussian blur. This #### convolve(kernel) -Convolve the image with the specified `kernel`. The kernel specification takes the following form: +Convolve the image with the specified `kernel`, an Object with the following attributes: -* `kernel = ` - `{ 'width': N` - `, 'height': M` - `, 'scale': Z` - `, 'offset': Y` - `, 'kernel':` - ` [ 1, 2, 3,` - ` 4, 5, 6,` - ` 7, 8, 9 ]` - `}` +* `width` is an integral Number representing the width of the kernel in pixels. +* `height` is an integral Number representing the width of the kernel in pixels. +* `kernel` is an Array of length `width*height` containing the kernel values. +* `scale`, if present, is a Number representing the scale of the kernel in pixels, defaulting to the sum of the kernel's values. +* `offset`, if present, is a Number representing the offset of the kernel in pixels, defaulting to 0. + +```javascript +sharp(input) + .convolve({ + width: 3, + height: 3, + kernel: [-1, 0, 1, -2, 0, 2, -1, 0, 1] + }) + .raw() + .toBuffer(function(err, data, info) { + // data contains the raw pixel data representing the input image + // convolved with the horizontal Sobel operator + }); +``` #### sharpen([sigma], [flat], [jagged]) diff --git a/docs/changelog.md b/docs/changelog.md index c805fecf..202c7fc2 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -30,6 +30,10 @@ Requires libvips v8.3.1 [#456](https://github.com/lovell/sharp/pull/456) [@kapouer](https://github.com/kapouer) +* Add convolve operation for kernel-based convolution. + [#479](https://github.com/lovell/sharp/pull/479) + [@mhirsch](https://github.com/mhirsch) + * Add greyscale option to threshold operation for colourspace conversion control. [#480](https://github.com/lovell/sharp/pull/480) [@mhirsch](https://github.com/mhirsch) diff --git a/index.js b/index.js index 34d31735..f53838bd 100644 --- a/index.js +++ b/index.js @@ -450,18 +450,7 @@ Sharp.prototype.blur = function(sigma) { /* Convolve the image with a kernel. - Call with an object of the following form: - { 'width': N - , 'height': M - , 'scale': Z - , 'offset': Y - , 'kernel': - [ 1, 2, 3, - 4, 5, 6, - 7, 8, 9 ] - } */ - Sharp.prototype.convolve = function(kernel) { if (!isDefined(kernel) || !isDefined(kernel.kernel) || !isDefined(kernel.width) || !isDefined(kernel.height) || diff --git a/src/operations.cc b/src/operations.cc index 6adfe165..0c2f1e65 100644 --- a/src/operations.cc +++ b/src/operations.cc @@ -215,8 +215,10 @@ namespace sharp { /* * Convolution with a kernel. */ - VImage Convolve(VImage image, int width, int height, double scale, double offset, - const std::unique_ptr &kernel_v) { + VImage Convolve(VImage image, int const width, int const height, + double const scale, double const offset, + std::unique_ptr const &kernel_v + ) { VImage kernel = VImage::new_from_memory( kernel_v.get(), width * height * sizeof(double), diff --git a/src/operations.h b/src/operations.h index 2b307e82..43fd9213 100644 --- a/src/operations.h +++ b/src/operations.h @@ -38,8 +38,8 @@ namespace sharp { /* * Convolution with a kernel. */ - VImage Convolve(VImage image, int width, int height, double scale, double offset, - const std::unique_ptr &kernel_v); + VImage Convolve(VImage image, int const width, int const height, + double const scale, double const offset, std::unique_ptr const &kernel_v); /* * Sharpen flat and jagged areas. Use sigma of -1.0 for fast sharpen. diff --git a/src/pipeline.cc b/src/pipeline.cc index 3c4476b2..85278037 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -640,9 +640,10 @@ class PipelineWorker : public AsyncWorker { // Convolve if (shouldConv) { image = Convolve(image, - baton->convKernelWidth, baton->convKernelHeight, - baton->convKernelScale, baton->convKernelOffset, - baton->convKernel); + baton->convKernelWidth, baton->convKernelHeight, + baton->convKernelScale, baton->convKernelOffset, + baton->convKernel + ); } // Sharpen @@ -1165,13 +1166,12 @@ NAN_METHOD(pipeline) { // Convolution Kernel if(Has(options, New("convKernel").ToLocalChecked()).FromJust()) { Local kernel = Get(options, New("convKernel").ToLocalChecked()).ToLocalChecked().As(); - baton->convKernelWidth = attrAs(kernel, "width"); - baton->convKernelHeight = attrAs(kernel, "height"); + baton->convKernelWidth = attrAs(kernel, "width"); + baton->convKernelHeight = attrAs(kernel, "height"); baton->convKernelScale = attrAs(kernel, "scale"); baton->convKernelOffset = attrAs(kernel, "offset"); - size_t kernelSize = baton->convKernelWidth * baton->convKernelHeight; - + size_t const kernelSize = static_cast(baton->convKernelWidth * baton->convKernelHeight); baton->convKernel = std::unique_ptr(new double[kernelSize]); Local kdata = Get(kernel, New("kernel").ToLocalChecked()).ToLocalChecked().As(); for(unsigned int i = 0; i < kernelSize; i++) {