Skip to content

Commit

Permalink
Add centre/center option to tile-based output (#2397)
Browse files Browse the repository at this point in the history
  • Loading branch information
beig authored Oct 8, 2020
1 parent 9704ca4 commit c213e98
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/api-output.md
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ Warning: multiple sharp instances concurrently producing tile output can expose
- `options.skipBlanks` **[number][9]** threshold to skip tile generation, a value 0 - 255 for 8-bit images or 0 - 65535 for 16-bit images (optional, default `-1`)
- `options.container` **[string][2]** tile container, with value `fs` (filesystem) or `zip` (compressed file). (optional, default `'fs'`)
- `options.layout` **[string][2]** filesystem layout, possible values are `dz`, `iiif`, `zoomify` or `google`. (optional, default `'dz'`)
- `options.centre|center` **[boolean][7]** center image in tile (optional, default `false`)

### Examples

Expand Down
1 change: 1 addition & 0 deletions lib/constructor.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ const Sharp = function (input, options) {
tileAngle: 0,
tileSkipBlanks: -1,
tileBackground: [255, 255, 255, 255],
tileCentre: false,
linearA: 1,
linearB: 0,
// Function to notify of libvips warnings
Expand Down
5 changes: 5 additions & 0 deletions lib/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,7 @@ function raw () {
* @param {number} [options.skipBlanks=-1] threshold to skip tile generation, a value 0 - 255 for 8-bit images or 0 - 65535 for 16-bit images
* @param {string} [options.container='fs'] tile container, with value `fs` (filesystem) or `zip` (compressed file).
* @param {string} [options.layout='dz'] filesystem layout, possible values are `dz`, `iiif`, `zoomify` or `google`.
* @param {boolean} [options.centre=false] center image in tile.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
Expand Down Expand Up @@ -726,6 +727,10 @@ function tile (options) {
} else if (is.defined(options.layout) && options.layout === 'google') {
this.options.tileSkipBlanks = 5;
}
// Center image in tile
if (is.defined(options.centre) || is.defined(options.center)) {
this._setBooleanOption('tileCentre', options.centre || options.center);
}
}
// Format
if (is.inArray(this.options.formatOut, ['jpeg', 'png', 'webp'])) {
Expand Down
2 changes: 2 additions & 0 deletions src/pipeline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,7 @@ class PipelineWorker : public Napi::AsyncWorker {
->set("suffix", const_cast<char*>(suffix.data()))
->set("angle", CalculateAngleRotation(baton->tileAngle))
->set("background", baton->tileBackground)
->set("centre", baton->tileCentre)
->set("skip_blanks", baton->tileSkipBlanks);
// libvips chooses a default depth based on layout. Instead of replicating that logic here by
// not passing anything - libvips will handle choice
Expand Down Expand Up @@ -1403,6 +1404,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
baton->tileDepth = static_cast<VipsForeignDzDepth>(
vips_enum_from_nick(nullptr, VIPS_TYPE_FOREIGN_DZ_DEPTH,
sharp::AttrAsStr(options, "tileDepth").data()));
baton->tileCentre = sharp::AttrAsBool(options, "tileCentre");

// Force random access for certain operations
if (baton->input->access == VIPS_ACCESS_SEQUENTIAL) {
Expand Down
1 change: 1 addition & 0 deletions src/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ struct PipelineBaton {
int cropOffsetLeft;
int cropOffsetTop;
bool premultiplied;
bool tileCentre;
std::string kernel;
bool fastShrinkOnLoad;
double tintA;
Expand Down
Binary file added test/fixtures/expected/tile_centered.jpg
Loading
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/tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,14 @@ describe('Tile', function () {
});
});

it('Invalid center parameter value fail', function () {
assert.throws(function () {
sharp().tile({
center: 'true'
});
});
});

it('Deep Zoom layout', function (done) {
const directory = fixtures.path('output.dzi_files');
rimraf(directory, function () {
Expand Down Expand Up @@ -765,6 +773,46 @@ describe('Tile', function () {
});
});

it('Google layout with center image in tile', function (done) {
const directory = fixtures.path('output.google_center.dzi');
rimraf(directory, function () {
sharp(fixtures.inputJpg)
.tile({
center: true,
layout: 'google'
})
.toFile(directory, function (err, info) {
if (err) throw err;
assert.strictEqual('dz', info.format);
assert.strictEqual(2725, info.width);
assert.strictEqual(2225, info.height);
assert.strictEqual(3, info.channels);
assert.strictEqual('number', typeof info.size);
fixtures.assertSimilar(fixtures.expected('tile_centered.jpg'), fs.readFileSync(path.join(directory, '0', '0', '0.jpg')), done);
});
});
});

it('Google layout with center image in tile centre', function (done) {
const directory = fixtures.path('output.google_center.dzi');
rimraf(directory, function () {
sharp(fixtures.inputJpg)
.tile({
centre: true,
layout: 'google'
})
.toFile(directory, function (err, info) {
if (err) throw err;
assert.strictEqual('dz', info.format);
assert.strictEqual(2725, info.width);
assert.strictEqual(2225, info.height);
assert.strictEqual(3, info.channels);
assert.strictEqual('number', typeof info.size);
fixtures.assertSimilar(fixtures.expected('tile_centered.jpg'), fs.readFileSync(path.join(directory, '0', '0', '0.jpg')), done);
});
});
});

it('IIIF layout', function (done) {
const directory = fixtures.path('output.iiif.info');
rimraf(directory, function () {
Expand Down

0 comments on commit c213e98

Please sign in to comment.