mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Add 'clone' method to snapshot an instance
Cloned instances share a common input Allows multiple output Streams to use a single input Stream
This commit is contained in:
parent
1091be374e
commit
86490bedfb
17
README.md
17
README.md
@ -163,6 +163,15 @@ var pipeline = sharp()
|
|||||||
readableStream.pipe(pipeline);
|
readableStream.pipe(pipeline);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var pipeline = sharp().rotate();
|
||||||
|
pipeline.clone().resize(800, 600).pipe(firstWritableStream);
|
||||||
|
pipeline.clone().extract(20, 20, 100, 100).pipe(secondWritableStream);
|
||||||
|
readableStream.pipe(pipeline);
|
||||||
|
// firstWritableStream receives auto-rotated, resized readableStream
|
||||||
|
// secondWritableStream receives auto-rotated, extracted region of readableStream
|
||||||
|
```
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
sharp('input.png')
|
sharp('input.png')
|
||||||
.rotate(180)
|
.rotate(180)
|
||||||
@ -347,6 +356,14 @@ Do not process input images where the number of pixels (width * height) exceeds
|
|||||||
|
|
||||||
`pixels` is the integral Number of pixels, with a value between 1 and the default 268402689 (0x3FFF * 0x3FFF).
|
`pixels` is the integral Number of pixels, with a value between 1 and the default 268402689 (0x3FFF * 0x3FFF).
|
||||||
|
|
||||||
|
#### clone()
|
||||||
|
|
||||||
|
Takes a "snapshot" of the instance, returning a new instance.
|
||||||
|
Cloned instances inherit the input of their parent instance.
|
||||||
|
This allows multiple output Streams
|
||||||
|
and therefore multiple processing pipelines
|
||||||
|
to share a single input Stream.
|
||||||
|
|
||||||
### Image transformation options
|
### Image transformation options
|
||||||
|
|
||||||
#### resize(width, [height])
|
#### resize(width, [height])
|
||||||
|
18
index.js
18
index.js
@ -760,6 +760,24 @@ Sharp.prototype.metadata = function(callback) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Clone new instance using existing options.
|
||||||
|
Cloned instances share the same input.
|
||||||
|
*/
|
||||||
|
Sharp.prototype.clone = function() {
|
||||||
|
// Clone existing options
|
||||||
|
var clone = new Sharp();
|
||||||
|
util._extend(clone.options, this.options);
|
||||||
|
clone.streamIn = false;
|
||||||
|
// Pass 'finish' event to clone for Stream-based input
|
||||||
|
this.on('finish', function() {
|
||||||
|
// Clone inherits input data
|
||||||
|
clone.options.bufferIn = this.options.bufferIn;
|
||||||
|
clone.emit('finish');
|
||||||
|
});
|
||||||
|
return clone;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get and set cache memory and item limits
|
Get and set cache memory and item limits
|
||||||
*/
|
*/
|
||||||
|
@ -1222,7 +1222,6 @@ NAN_METHOD(pipeline) {
|
|||||||
baton->bufferInLength = node::Buffer::Length(buffer);
|
baton->bufferInLength = node::Buffer::Length(buffer);
|
||||||
baton->bufferIn = new char[baton->bufferInLength];
|
baton->bufferIn = new char[baton->bufferInLength];
|
||||||
memcpy(baton->bufferIn, node::Buffer::Data(buffer), baton->bufferInLength);
|
memcpy(baton->bufferIn, node::Buffer::Data(buffer), baton->bufferInLength);
|
||||||
options->Set(NanNew<String>("bufferIn"), NanNull());
|
|
||||||
}
|
}
|
||||||
// ICC profile to use when input CMYK image has no embedded profile
|
// ICC profile to use when input CMYK image has no embedded profile
|
||||||
baton->iccProfilePath = *String::Utf8Value(options->Get(NanNew<String>("iccProfilePath"))->ToString());
|
baton->iccProfilePath = *String::Utf8Value(options->Get(NanNew<String>("iccProfilePath"))->ToString());
|
||||||
|
58
test/unit/clone.js
Executable file
58
test/unit/clone.js
Executable file
@ -0,0 +1,58 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var fs = require('fs');
|
||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
|
var sharp = require('../../index');
|
||||||
|
var fixtures = require('../fixtures');
|
||||||
|
|
||||||
|
sharp.cache(0);
|
||||||
|
|
||||||
|
describe('Clone', function() {
|
||||||
|
it('Read from Stream and write to multiple Streams', function(done) {
|
||||||
|
var finishEventsExpected = 2;
|
||||||
|
// Output stream 1
|
||||||
|
var output1 = fixtures.path('output.multi-stream.1.jpg');
|
||||||
|
var writable1 = fs.createWriteStream(output1);
|
||||||
|
writable1.on('finish', function() {
|
||||||
|
sharp(output1).toBuffer(function(err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, data.length > 0);
|
||||||
|
assert.strictEqual(data.length, info.size);
|
||||||
|
assert.strictEqual('jpeg', info.format);
|
||||||
|
assert.strictEqual(320, info.width);
|
||||||
|
assert.strictEqual(240, info.height);
|
||||||
|
fs.unlinkSync(output1);
|
||||||
|
finishEventsExpected--;
|
||||||
|
if (finishEventsExpected === 0) {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// Output stream 2
|
||||||
|
var output2 = fixtures.path('output.multi-stream.2.jpg');
|
||||||
|
var writable2 = fs.createWriteStream(output2);
|
||||||
|
writable2.on('finish', function() {
|
||||||
|
sharp(output2).toBuffer(function(err, data, info) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, data.length > 0);
|
||||||
|
assert.strictEqual(data.length, info.size);
|
||||||
|
assert.strictEqual('jpeg', info.format);
|
||||||
|
assert.strictEqual(100, info.width);
|
||||||
|
assert.strictEqual(122, info.height);
|
||||||
|
fs.unlinkSync(output2);
|
||||||
|
finishEventsExpected--;
|
||||||
|
if (finishEventsExpected === 0) {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// Create parent instance
|
||||||
|
var rotator = sharp().rotate(90);
|
||||||
|
// Cloned instances with differing dimensions
|
||||||
|
rotator.clone().resize(320, 240).pipe(writable1);
|
||||||
|
rotator.clone().resize(100).pipe(writable2);
|
||||||
|
// Go
|
||||||
|
fs.createReadStream(fixtures.inputJpg).pipe(rotator);
|
||||||
|
});
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user