Skip to content

Commit

Permalink
Merge a824507 into 65b7f7d
Browse files Browse the repository at this point in the history
  • Loading branch information
mhirsch committed Jul 7, 2016
2 parents 65b7f7d + a824507 commit 9328a1d
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 0 deletions.
19 changes: 19 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,25 @@ sharp(input)
});
```

#### extractChannel(channel)

Extract a channel from the image. The following channel names are equivalent:

* Red: `0, 'red'`
* Green: `1, 'green'`
* Blue: `2, 'blue'`

The result will be a single-channel grayscale image.

```javascript
sharp(input)
.extractChannel('green')
.toFile('input_green.jpg',function(err, info) {
// info.channels === 1
// input_green.jpg contains the green channel of the input image
});
```

#### background(rgba)

Set the background for the `embed`, `flatten` and `extend` operations.
Expand Down
16 changes: 16 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ var Sharp = function(input, options) {
withMetadataOrientation: -1,
tileSize: 256,
tileOverlap: 0,
extractChannel: -1,
// Function to notify of queue length changes
queueListener: function(queueLength) {
module.exports.queue.emit('change', queueLength);
Expand Down Expand Up @@ -302,6 +303,21 @@ Sharp.prototype.extract = function(options) {
return this;
};

Sharp.prototype.extractChannel = function(channel) {
if (channel === 'red')
channel = 0;
else if (channel === 'green')
channel = 1;
else if (channel === 'blue')
channel = 2;
if(isInteger(channel) && inRange(channel,0,4)) {
this.options.extractChannel = channel;
} else {
throw new Error('Cannot extract invalid channel ' + channel);
}
return this;
};

/*
Set the background colour for embed and flatten operations.
Delegates to the 'Color' module, which can throw an Error
Expand Down
10 changes: 10 additions & 0 deletions src/pipeline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,15 @@ class PipelineWorker : public AsyncWorker {
image = Bandbool(image, baton->bandBoolOp);
}

// Extract an image channel (aka vips band)
if(baton->extractChannel > -1) {
if(baton->extractChannel >= image.bands()) {
(baton->err).append("Cannot extract channel from image. Too few channels in image.");
return Error();
}
image = image.extract_band(baton->extractChannel);
}

// Override EXIF Orientation tag
if (baton->withMetadata && baton->withMetadataOrientation != -1) {
SetExifOrientation(image, baton->withMetadataOrientation);
Expand Down Expand Up @@ -1156,6 +1165,7 @@ NAN_METHOD(pipeline) {
baton->extendBottom = attrAs<int32_t>(options, "extendBottom");
baton->extendLeft = attrAs<int32_t>(options, "extendLeft");
baton->extendRight = attrAs<int32_t>(options, "extendRight");
baton->extractChannel = attrAs<int32_t>(options, "extractChannel");
// Output options
baton->progressive = attrAs<bool>(options, "progressive");
baton->quality = attrAs<int32_t>(options, "quality");
Expand Down
2 changes: 2 additions & 0 deletions src/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ struct PipelineBaton {
double convKernelScale;
double convKernelOffset;
VipsOperationBoolean bandBoolOp;
int extractChannel;
int tileSize;
int tileOverlap;
VipsForeignDzContainer tileContainer;
Expand Down Expand Up @@ -153,6 +154,7 @@ struct PipelineBaton {
convKernelScale(0.0),
convKernelOffset(0.0),
bandBoolOp(VIPS_OPERATION_BOOLEAN_LAST),
extractChannel(-1),
tileSize(256),
tileOverlap(0),
tileContainer(VIPS_FOREIGN_DZ_CONTAINER_FS),
Expand Down
Binary file added test/fixtures/expected/extract-blue.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/expected/extract-red.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions test/unit/extractChannel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict';

var assert = require('assert');

var sharp = require('../../index');
var fixtures = require('../fixtures');

describe('Image channel extraction', function() {

it('Red channel', function(done) {
sharp(fixtures.inputJpg)
.extractChannel('red')
.resize(320,240)
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
fixtures.assertSimilar(fixtures.expected('extract-red.jpg'), data, { threshold: 8 }, done);
});
});

it('Blue channel', function(done) {
sharp(fixtures.inputJpg)
.extractChannel(2)
.resize(320,240)
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
fixtures.assertSimilar(fixtures.expected('extract-blue.jpg'), data, { threshold: 8 }, done);
});
});

it('Invalid channel number', function() {
assert.throws(function() {
sharp(fixtures.inputJpg)
.extractChannel(-1);
});
});

it('No arguments', function() {
assert.throws(function() {
sharp(fixtures.inputJpg)
.extractChannel();
});
});

});

0 comments on commit 9328a1d

Please sign in to comment.